Add parsing for function calls
This commit is contained in:
parent
389d4b47ff
commit
813a6c7827
|
@ -304,7 +304,7 @@ void ParseGlobals();
|
|||
struct ASTNode* ParseFunction(int Type);
|
||||
struct ASTNode* ParseCompound();
|
||||
|
||||
|
||||
struct ASTNode* GetExpressionList();
|
||||
struct ASTNode* CallFunction();
|
||||
struct ASTNode* ReturnStatement();
|
||||
|
||||
|
@ -409,6 +409,8 @@ void AsLabel(int Label);
|
|||
int AsShl(int Register, int Val);
|
||||
|
||||
int AsReturn(int Register, int FuncID);
|
||||
int AsCallWrapper(struct ASTNode* Node);
|
||||
void AsCopyArgs(int Register, int Position);
|
||||
int AsCall(int Register, int FuncID);
|
||||
|
||||
int AsWhile(struct ASTNode* Node);
|
||||
|
|
|
@ -66,6 +66,9 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
|
|||
DeallocateAllRegisters();
|
||||
return -1;
|
||||
|
||||
case OP_CALL:
|
||||
return (AsCallWrapper(Node));
|
||||
|
||||
case OP_FUNC:
|
||||
AsFunctionPreamble(Node->Value.ID);
|
||||
AssembleTree(Node->Left, -1, Node->Operation);
|
||||
|
@ -141,12 +144,9 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
|
|||
return LeftVal; //AsWiden(LeftVal, Node->Left->ExprType, Node->ExprType);
|
||||
|
||||
case OP_RET:
|
||||
printf("\tReturning from %s, %d\n", Symbols[Node->Value.ID].Name, Node->Value.ID);
|
||||
AsReturn(LeftVal, CurrentFunction);
|
||||
return -1;
|
||||
|
||||
case OP_CALL:
|
||||
printf("\tReturning from %s, %d\n", Symbols[Node->Value.ID].Name, Node->Value.ID);
|
||||
return AsCall(LeftVal, Node->Value.ID);
|
||||
|
||||
/* case OP_EQUAL:
|
||||
return AsEqual(LeftVal, RightVal);
|
||||
|
@ -739,18 +739,42 @@ void AsGlobalSymbol(int ID) {
|
|||
}
|
||||
}
|
||||
|
||||
int AsCall(int Register, int FuncID) {
|
||||
int AsCallWrapper(struct ASTNode* Node) {
|
||||
struct ASTNode* CompositeTree = Node->Left;
|
||||
int Register, Args = 0;
|
||||
|
||||
while(CompositeTree) {
|
||||
Register = AssembleTree(CompositeTree->Right, -1, CompositeTree->Operation);
|
||||
AsCopyArgs(Register, CompositeTree->Value.Size);
|
||||
if(Args == 0) Args = CompositeTree->Value.Size;
|
||||
DeallocateAllRegisters();
|
||||
CompositeTree = CompositeTree->Left;
|
||||
}
|
||||
|
||||
return AsCall(Node->Value.ID, Args);
|
||||
}
|
||||
|
||||
void AsCopyArgs(int Register, int Position) {
|
||||
if(Position > 4) { // Args above 4 go on the stack
|
||||
fprintf(OutputFile, "\tpushq\t%s\n", Registers[Register]);
|
||||
} else {
|
||||
fprintf(OutputFile, "\tmovq\t%s, %s\n", Registers[Register], Registers[10 - Position]);
|
||||
}
|
||||
}
|
||||
|
||||
int AsCall(int FuncID, int Args) {
|
||||
|
||||
int OutRegister = RetrieveRegister();
|
||||
|
||||
printf("\t\tCalling function %s with parameter %s\n", Symbols[FuncID].Name, Registers[Register]);
|
||||
printf("\t\tCalling function %s with %d parameters\n", Symbols[FuncID].Name, Args);
|
||||
printf("\t\t\tFunction returns into %s\n", Registers[OutRegister]);
|
||||
|
||||
fprintf(OutputFile, "\tmovq\t%s, %%rcx\n", Registers[Register]);
|
||||
fprintf(OutputFile, "\tcall\t%s\n", Symbols[FuncID].Name);
|
||||
if(Args > 4)
|
||||
fprintf(OutputFile, "\taddq\t$%d, %%rsp\n", 8 * (Args - 4));
|
||||
|
||||
fprintf(OutputFile, "\tmovq\t%%rax, %s\n", Registers[OutRegister]);
|
||||
|
||||
DeallocateRegister(Register);
|
||||
return OutRegister;
|
||||
}
|
||||
|
||||
|
@ -897,10 +921,9 @@ void AssemblerPreamble() {
|
|||
|
||||
void AsFunctionPreamble(int FunctionID) {
|
||||
char* Name = Symbols[FunctionID].Name;
|
||||
int ParamOffset = 48, ParamReg = 9;
|
||||
int ParamOffset = 0, ParamReg = 9;
|
||||
|
||||
|
||||
AsNewStackFrame();
|
||||
LocalVarOffset = 4; // Prepare parameters
|
||||
|
||||
fprintf(OutputFile,
|
||||
"\t.text\n"
|
||||
|
@ -932,7 +955,7 @@ void AsFunctionPreamble(int FunctionID) {
|
|||
// If we have more parameters, move them to the stack
|
||||
for(; LoopIndex > CurrentLocal; LoopIndex--) {
|
||||
if(Symbols[LoopIndex].Storage == SC_PARAM) {
|
||||
Symbols[LoopIndex].SinkOffset = ParamOffset;
|
||||
Symbols[LoopIndex].SinkOffset = ParamOffset + 16;
|
||||
ParamOffset += 8;
|
||||
} else {
|
||||
Symbols[LoopIndex].SinkOffset = AsCalcOffset(Symbols[LoopIndex].Type);
|
||||
|
@ -940,7 +963,7 @@ void AsFunctionPreamble(int FunctionID) {
|
|||
}
|
||||
|
||||
// With all the parameters on the stack, we can allocate the shadow space
|
||||
StackFrameOffset = (LocalVarOffset + 31) & ~31;
|
||||
StackFrameOffset = ((LocalVarOffset + 31) & ~31);
|
||||
fprintf(OutputFile,
|
||||
"\taddq\t$%d, %%rsp\n", -StackFrameOffset);
|
||||
|
||||
|
|
27
src/Parser.c
27
src/Parser.c
|
@ -158,7 +158,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
|
|||
|
||||
NodeType = CurrentToken.type;
|
||||
//printf("%d\r\n", CurrentToken.type);
|
||||
if(NodeType == LI_SEMIC || NodeType == LI_RPARE || NodeType == LI_RBRAS) {
|
||||
if(NodeType == LI_SEMIC || NodeType == LI_RPARE || NodeType == LI_RBRAS || NodeType == LI_COM) {
|
||||
//printf("Current token matches ; ) ]\r\n");
|
||||
LeftNode->RVal = 1; return LeftNode;
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ struct ASTNode* CallFunction() {
|
|||
|
||||
VerifyToken(LI_LPARE, "(");
|
||||
|
||||
Tree = ParsePrecedenceASTNode(0);
|
||||
Tree = GetExpressionList();
|
||||
|
||||
Tree = ConstructASTBranch(OP_CALL, Symbols[FuncID].Type, Tree, FuncID);
|
||||
|
||||
|
@ -382,6 +382,29 @@ struct ASTNode* CallFunction() {
|
|||
return Tree;
|
||||
}
|
||||
|
||||
struct ASTNode* GetExpressionList() {
|
||||
struct ASTNode* Tree = NULL, *Child = NULL;
|
||||
int Count;
|
||||
|
||||
while(CurrentToken.type != LI_RPARE) {
|
||||
Child = ParsePrecedenceASTNode(0);
|
||||
Count++;
|
||||
|
||||
Tree = ConstructASTNode(OP_COMP, PTR_VOID, Tree, NULL, Child, Count);
|
||||
|
||||
switch(CurrentToken.type) {
|
||||
case LI_COM:
|
||||
Tokenise(&CurrentToken);
|
||||
break;
|
||||
case LI_RPARE:
|
||||
break;
|
||||
default:
|
||||
Die("Unexpected token in argument list");
|
||||
}
|
||||
}
|
||||
|
||||
return Tree;
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * *
|
||||
|
|
16
tests/parameters
Normal file
16
tests/parameters
Normal file
|
@ -0,0 +1,16 @@
|
|||
i32 :: params(int a, int b, int c, int d, int e, int f, int g, int h) {
|
||||
PrintInteger(a); PrintInteger(b); PrintInteger(c); PrintInteger(d); PrintInteger(e); PrintInteger(f); PrintInteger(g); PrintInteger(h);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int :: add(i32 a, i32 b, i32 c) {
|
||||
return (a + b + c);
|
||||
}
|
||||
|
||||
i32 :: main() {
|
||||
int Temp;
|
||||
params(1, 2, 3, 5, 8, 13, 21, 34);
|
||||
Temp = add(2, 3, 4);
|
||||
PrintInteger(Temp);
|
||||
return (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user