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