structure for system calls

main
cosmonaut 2021-06-02 12:33:01 -07:00
parent d9b01515eb
commit 506ee9ecad
6 changed files with 149 additions and 0 deletions

View File

@ -40,6 +40,7 @@
";" return SEMICOLON;
":" return COLON;
"?" return QUESTION;
"@" return AT;
"(" return LEFT_PAREN;
")" return RIGHT_PAREN;
"[" return LEFT_BRACKET;

View File

@ -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

View File

@ -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;
}
}

View File

@ -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));

View File

@ -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);

View File

@ -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();