forked from cosmonaut/wraith-lang
structure for system calls
parent
d9b01515eb
commit
506ee9ecad
|
@ -40,6 +40,7 @@
|
|||
";" return SEMICOLON;
|
||||
":" return COLON;
|
||||
"?" return QUESTION;
|
||||
"@" return AT;
|
||||
"(" return LEFT_PAREN;
|
||||
")" return RIGHT_PAREN;
|
||||
"[" return LEFT_BRACKET;
|
||||
|
|
|
@ -54,6 +54,7 @@ extern FILE *yyin;
|
|||
%token SEMICOLON
|
||||
%token COLON
|
||||
%token QUESTION
|
||||
%token AT
|
||||
%token LEFT_PAREN
|
||||
%token RIGHT_PAREN
|
||||
%token LEFT_BRACE
|
||||
|
@ -141,6 +142,11 @@ AccessExpression : Identifier POINT AccessExpression
|
|||
$$ = $1;
|
||||
}
|
||||
|
||||
SystemCallExpression : AT Identifier
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
Number : NUMBER
|
||||
{
|
||||
$$ = MakeNumberNode(yytext);
|
||||
|
@ -234,6 +240,10 @@ FunctionCallExpression : AccessExpression LEFT_PAREN Arguments RIGHT_PAREN
|
|||
{
|
||||
$$ = MakeFunctionCallExpressionNode($1, $3);
|
||||
}
|
||||
| SystemCallExpression LEFT_PAREN Arguments RIGHT_PAREN
|
||||
{
|
||||
$$ = MakeSystemCallExpressionNode($1, $3);
|
||||
}
|
||||
|
||||
PartialStatement : FunctionCallExpression
|
||||
| AssignmentStatement
|
||||
|
|
|
@ -13,6 +13,8 @@ struct Program {
|
|||
static Main(): int {
|
||||
x: int = 4;
|
||||
y: int = Foo.Func(x);
|
||||
addr: uint = @malloc(y);
|
||||
@free(addr);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
|
13
src/ast.c
13
src/ast.c
|
@ -67,6 +67,8 @@ const char *SyntaxKindString(SyntaxKind syntaxKind)
|
|||
return "StringLiteral";
|
||||
case StructDeclaration:
|
||||
return "StructDeclaration";
|
||||
case SystemCall:
|
||||
return "SystemCall";
|
||||
case Type:
|
||||
return "Type";
|
||||
case UnaryExpression:
|
||||
|
@ -426,6 +428,17 @@ Node *MakeFunctionCallExpressionNode(
|
|||
return node;
|
||||
}
|
||||
|
||||
Node *MakeSystemCallExpressionNode(
|
||||
Node *identifierNode,
|
||||
Node *argumentSequenceNode)
|
||||
{
|
||||
Node *node = (Node *)malloc(sizeof(Node));
|
||||
node->syntaxKind = SystemCall;
|
||||
node->systemCall.identifier = identifierNode;
|
||||
node->systemCall.argumentSequence = argumentSequenceNode;
|
||||
return node;
|
||||
}
|
||||
|
||||
Node *MakeAccessExpressionNode(Node *accessee, Node *accessor)
|
||||
{
|
||||
Node *node = (Node *)malloc(sizeof(Node));
|
||||
|
|
10
src/ast.h
10
src/ast.h
|
@ -44,6 +44,7 @@ typedef enum
|
|||
StaticModifier,
|
||||
StringLiteral,
|
||||
StructDeclaration,
|
||||
SystemCall,
|
||||
Type,
|
||||
UnaryExpression
|
||||
} SyntaxKind;
|
||||
|
@ -287,6 +288,12 @@ struct Node
|
|||
Node *declarationSequence;
|
||||
} structDeclaration;
|
||||
|
||||
struct
|
||||
{
|
||||
Node *identifier;
|
||||
Node *argumentSequence;
|
||||
} systemCall;
|
||||
|
||||
struct
|
||||
{
|
||||
Node *typeNode;
|
||||
|
@ -349,6 +356,9 @@ Node *MakeEmptyFunctionArgumentSequenceNode();
|
|||
Node *MakeFunctionCallExpressionNode(
|
||||
Node *identifierNode,
|
||||
Node *argumentSequenceNode);
|
||||
Node *MakeSystemCallExpressionNode(
|
||||
Node *identifierNode,
|
||||
Node *argumentSequenceNode);
|
||||
Node *MakeAccessExpressionNode(Node *accessee, Node *accessor);
|
||||
Node *MakeAllocNode(Node *typeNode);
|
||||
Node *MakeIfNode(Node *expressionNode, Node *statementSequenceNode);
|
||||
|
|
113
src/codegen.c
113
src/codegen.c
|
@ -112,6 +112,16 @@ typedef struct StructTypeDeclaration
|
|||
StructTypeDeclaration *structTypeDeclarations;
|
||||
uint32_t structTypeDeclarationCount;
|
||||
|
||||
typedef struct SystemFunction
|
||||
{
|
||||
char *name;
|
||||
LLVMTypeRef functionType;
|
||||
LLVMValueRef function;
|
||||
} SystemFunction;
|
||||
|
||||
SystemFunction *systemFunctions;
|
||||
uint32_t systemFunctionCount;
|
||||
|
||||
/* FUNCTION FORWARD DECLARATIONS */
|
||||
static LLVMBasicBlockRef CompileStatement(
|
||||
LLVMModuleRef module,
|
||||
|
@ -262,6 +272,36 @@ static LLVMTypeRef ResolveType(TypeTag *typeTag)
|
|||
}
|
||||
}
|
||||
|
||||
static void AddSystemFunction(
|
||||
char *name,
|
||||
LLVMTypeRef functionType,
|
||||
LLVMValueRef function)
|
||||
{
|
||||
systemFunctions = realloc(
|
||||
systemFunctions,
|
||||
sizeof(SystemFunction) * (systemFunctionCount + 1));
|
||||
systemFunctions[systemFunctionCount].name = strdup(name);
|
||||
systemFunctions[systemFunctionCount].functionType = functionType;
|
||||
systemFunctions[systemFunctionCount].function = function;
|
||||
systemFunctionCount += 1;
|
||||
}
|
||||
|
||||
static SystemFunction *LookupSystemFunction(char *name)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < systemFunctionCount; i += 1)
|
||||
{
|
||||
if (strcmp(name, systemFunctions[i].name) == 0)
|
||||
{
|
||||
return &systemFunctions[i];
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s %s %s", "System function", name, "not found!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void AddLocalVariable(
|
||||
Scope *scope,
|
||||
LLVMValueRef pointer, /* can be NULL */
|
||||
|
@ -1133,6 +1173,51 @@ static LLVMValueRef CompileFunctionCallExpression(
|
|||
return LLVMBuildCall(builder, function, args, argumentCount, returnName);
|
||||
}
|
||||
|
||||
static LLVMValueRef CompileSystemCallExpression(
|
||||
LLVMModuleRef module,
|
||||
LLVMBuilderRef builder,
|
||||
Node *systemCallExpression)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t argumentCount = systemCallExpression->systemCall.argumentSequence
|
||||
->functionArgumentSequence.count;
|
||||
LLVMValueRef args[argumentCount];
|
||||
char *returnName = "";
|
||||
|
||||
for (i = 0; i < systemCallExpression->systemCall.argumentSequence
|
||||
->functionArgumentSequence.count;
|
||||
i += 1)
|
||||
{
|
||||
args[i] = CompileExpression(
|
||||
module,
|
||||
builder,
|
||||
systemCallExpression->systemCall.argumentSequence
|
||||
->functionArgumentSequence.sequence[i]);
|
||||
}
|
||||
|
||||
SystemFunction *systemFunction = LookupSystemFunction(
|
||||
systemCallExpression->systemCall.identifier->identifier.name);
|
||||
|
||||
if (systemFunction == NULL)
|
||||
{
|
||||
fprintf(stderr, "System function not found!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (LLVMGetTypeKind(LLVMGetReturnType(systemFunction->functionType)) !=
|
||||
LLVMVoidTypeKind)
|
||||
{
|
||||
returnName = "callReturn";
|
||||
}
|
||||
|
||||
return LLVMBuildCall(
|
||||
builder,
|
||||
systemFunction->function,
|
||||
args,
|
||||
argumentCount,
|
||||
returnName);
|
||||
}
|
||||
|
||||
static LLVMValueRef CompileAccessExpressionForStore(
|
||||
LLVMBuilderRef builder,
|
||||
Node *accessExpression)
|
||||
|
@ -1196,6 +1281,9 @@ static LLVMValueRef CompileExpression(
|
|||
|
||||
case StringLiteral:
|
||||
return CompileString(builder, expression);
|
||||
|
||||
case SystemCall:
|
||||
return CompileSystemCallExpression(module, builder, expression);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown expression kind!\n");
|
||||
|
@ -1516,6 +1604,10 @@ static LLVMBasicBlockRef CompileStatement(
|
|||
|
||||
case ReturnVoid:
|
||||
return CompileReturnVoid(builder, function);
|
||||
|
||||
case SystemCall:
|
||||
CompileSystemCallExpression(module, builder, statement);
|
||||
return LLVMGetLastBasicBlock(function);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown statement kind!\n");
|
||||
|
@ -1812,6 +1904,24 @@ static void RegisterLibraryFunctions(
|
|||
LLVMInt8Type(),
|
||||
1,
|
||||
"PrintLine");
|
||||
|
||||
LLVMTypeRef mallocArg = LLVMInt64Type();
|
||||
LLVMTypeRef mallocFunctionType =
|
||||
LLVMFunctionType(LLVMInt64Type(), &mallocArg, 1, 0);
|
||||
LLVMValueRef mallocFunction =
|
||||
LLVMAddFunction(module, "malloc", mallocFunctionType);
|
||||
LLVMSetLinkage(mallocFunction, LLVMExternalLinkage);
|
||||
|
||||
AddSystemFunction("malloc", mallocFunctionType, mallocFunction);
|
||||
|
||||
LLVMTypeRef freeArg = LLVMInt64Type();
|
||||
LLVMTypeRef freeFunctionType =
|
||||
LLVMFunctionType(LLVMVoidType(), &freeArg, 1, 0);
|
||||
LLVMValueRef freeFunction =
|
||||
LLVMAddFunction(module, "free", freeFunctionType);
|
||||
LLVMSetLinkage(freeFunction, LLVMExternalLinkage);
|
||||
|
||||
AddSystemFunction("free", freeFunctionType, freeFunction);
|
||||
}
|
||||
|
||||
int Codegen(Node *node, uint32_t optimizationLevel)
|
||||
|
@ -1821,6 +1931,9 @@ int Codegen(Node *node, uint32_t optimizationLevel)
|
|||
structTypeDeclarations = NULL;
|
||||
structTypeDeclarationCount = 0;
|
||||
|
||||
systemFunctions = NULL;
|
||||
systemFunctionCount = 0;
|
||||
|
||||
LLVMModuleRef module = LLVMModuleCreateWithName("my_module");
|
||||
LLVMContextRef context = LLVMGetGlobalContext();
|
||||
|
||||
|
|
Loading…
Reference in New Issue