Add function prototyping - we can now call cstdlib functions

This commit is contained in:
Curle 2021-01-18 00:20:58 +00:00
parent 813a6c7827
commit 52134784a4
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
6 changed files with 87 additions and 27 deletions

View File

@ -426,7 +426,7 @@ void AsFunctionEpilogue(int ID);
* * * * D E C L A R A T I O N * * * * * * * * D E C L A R A T I O N * * * *
* * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * */
void BeginVariableDeclaration(int Type, int Scope, bool isParameter); void BeginVariableDeclaration(int Type, int Scope);
struct ASTNode* ParseIdentifier(void); struct ASTNode* ParseIdentifier(void);
struct ASTNode* IfStatement(); struct ASTNode* IfStatement();

View File

@ -179,6 +179,7 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
case REF_IDENT: case REF_IDENT:
//printf("\tReferencing variable %s %s with type %s and storage %d\r\n", Symbols[Node->Value.ID].Name, Node->RVal ? " rval " : "", ParentOp, Symbols[Node->Value.ID].Storage);
if(Node->RVal || ParentOp == OP_DEREF) { if(Node->RVal || ParentOp == OP_DEREF) {
if(Symbols[Node->Value.ID].Storage == SC_LOCAL || Symbols[Node->Value.ID].Storage == SC_PARAM) if(Symbols[Node->Value.ID].Storage == SC_LOCAL || Symbols[Node->Value.ID].Storage == SC_PARAM)
return AsLdLocalVar(Node->Value.ID, Node->Operation); return AsLdLocalVar(Node->Value.ID, Node->Operation);

View File

@ -13,7 +13,6 @@
int TypeSizes[9] = { 0, 1, 4, 8, 0, 8, 8, 8, 8}; // in BYTES int TypeSizes[9] = { 0, 1, 4, 8, 0, 8, 8, 8, 8}; // in BYTES
char* TokenNames[] = { char* TokenNames[] = {
"", // Push everything up by one
"End of file", "End of file",
"Equivalency", "Equivalency",
@ -46,6 +45,7 @@ char* TokenNames[] = {
"Bitwise Invert", "Bitwise Invert",
"Integer literal", "Integer literal",
"String literal",
"Statement End", "Statement End",
"Compound Block Start", "Compound Block Start",
@ -57,7 +57,6 @@ char* TokenNames[] = {
"Logical Block Start", "Logical Block Start",
"Logical Block End", "Logical Block End",
"Dereference operator",
"Comma", "Comma",
"Identifier", "Identifier",

View File

@ -130,7 +130,7 @@ struct ASTNode* ParsePrimary(void) {
case TY_IDENTIFIER: case TY_IDENTIFIER:
return PostfixStatement(); return PostfixStatement();
case LI_RPARE: case LI_LPARE:
// Starting a ( expr ) block // Starting a ( expr ) block
Tokenise(&CurrentToken); Tokenise(&CurrentToken);
@ -167,6 +167,8 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
while((OperatorPrecedence(NodeType) > PreviousTokenPrecedence) || (IsRightExpr(OpType) && OperatorPrecedence(OpType) == PreviousTokenPrecedence)) { while((OperatorPrecedence(NodeType) > PreviousTokenPrecedence) || (IsRightExpr(OpType) && OperatorPrecedence(OpType) == PreviousTokenPrecedence)) {
//printf("inside while\n"); //printf("inside while\n");
Tokenise(&CurrentToken); Tokenise(&CurrentToken);
if(CurrentToken.type == LI_RPARE)
break;
RightNode = ParsePrecedenceASTNode(Precedence[NodeType]); RightNode = ParsePrecedenceASTNode(Precedence[NodeType]);
@ -193,10 +195,9 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
//printf("\tAssigning variable: %s value %d\n", Symbols[FindSymbol(CurrentIdentifier)].Name, RightNode->Value.IntValue); //printf("\tAssigning variable: %s value %d\n", Symbols[FindSymbol(CurrentIdentifier)].Name, RightNode->Value.IntValue);
int currSymbolID = FindSymbol(CurrentIdentifier); // LeftNode holds the target, the target variable in this case
printf("\t\tAssigning variable: %s\n", Symbols[LeftNode->Value.ID].Name);
printf("\t\tAssigning variable: %s\n", Symbols[currSymbolID].Name); printf("\t\tAfter parsing, the identifier name is %s, id %d in the symbol table.\n", Symbols[LeftNode->Value.ID].Name, LeftNode->Value.ID);
printf("\t\tAfter parsing, the identifier name is %s, id %d in the symbol table.\n", CurrentIdentifier, FindSymbol(CurrentIdentifier));
LeftTemp = LeftNode; LeftTemp = LeftNode;
LeftNode = RightNode; LeftNode = RightNode;
@ -206,6 +207,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
RightTemp = NULL; RightTemp = NULL;
LeftTemp = NULL; LeftTemp = NULL;
} else { } else {
printf("\t\tAttempting to handle a %d in Binary Expression parsing\r\n", CurrentToken.type);
LeftNode->RVal = 1; LeftNode->RVal = 1;
RightNode->RVal = 1; RightNode->RVal = 1;
@ -422,7 +424,7 @@ struct ASTNode* ParseStatement(void) {
printf("\t\tNew Variable: %s\n", CurrentIdentifier); printf("\t\tNew Variable: %s\n", CurrentIdentifier);
Type = ParseOptionalPointer(); Type = ParseOptionalPointer();
VerifyToken(TY_IDENTIFIER, "ident"); VerifyToken(TY_IDENTIFIER, "ident");
BeginVariableDeclaration(Type, SC_LOCAL, false); BeginVariableDeclaration(Type, SC_LOCAL);
VerifyToken(LI_SEMIC, ";"); // TODO: single line assignment? VerifyToken(LI_SEMIC, ";"); // TODO: single line assignment?
return NULL; return NULL;
@ -504,12 +506,17 @@ void ParseGlobals() {
if(FunctionComing && CurrentToken.type == LI_LPARE) { if(FunctionComing && CurrentToken.type == LI_LPARE) {
printf("\tParsing function"); printf("\tParsing function");
Tree = ParseFunction(Type); Tree = ParseFunction(Type);
printf("\nBeginning assembler creation of new function %s\n", Symbols[Tree->Value.ID].Name); if(Tree) {
AssembleTree(Tree, -1, 0); printf("\nBeginning assembler creation of new function %s\n", Symbols[Tree->Value.ID].Name);
FreeLocals(); AssembleTree(Tree, -1, 0);
FreeLocals();
} else {
printf("\nFunction prototype saved\r\n");
}
} else { } else {
printf("\tParsing global variable declaration\n"); printf("\tParsing global variable declaration\n");
BeginVariableDeclaration(Type, SC_GLOBAL, false); BeginVariableDeclaration(Type, SC_GLOBAL);
VerifyToken(LI_SEMIC, ";");
} }
if(CurrentToken.type == LI_EOF) if(CurrentToken.type == LI_EOF)

View File

@ -8,14 +8,24 @@
#include <Data.h> #include <Data.h>
#include <stdbool.h> #include <stdbool.h>
static int ReadParameters() { static int ReadParameters(int FuncID) {
int TokenType, ParamCount = 0; int TokenType, ParamCount = 0, ProtoParamCount, ParamIndex;
ParamIndex = FuncID + 1;
if(ParamIndex) // If FuncID > -1 (If the function exists)
ProtoParamCount = Symbols[FuncID].Length; // Set the prototype length
while(CurrentToken.type != LI_RPARE) { while(CurrentToken.type != LI_RPARE) {
TokenType = ParseOptionalPointer(); TokenType = ParseOptionalPointer();
VerifyToken(TY_IDENTIFIER, "identifier"); VerifyToken(TY_IDENTIFIER, "identifier");
BeginVariableDeclaration(TokenType, SC_PARAM, true); if(ParamIndex) {
if(TokenType != Symbols[FuncID].Type)
DieDecimal("Function paramater of invalid type at index", ParamCount + 1);
ParamIndex++;
} else {
BeginVariableDeclaration(TokenType, SC_PARAM);
}
ParamCount++; ParamCount++;
switch(CurrentToken.type) { switch(CurrentToken.type) {
@ -29,6 +39,9 @@ static int ReadParameters() {
} }
} }
if((FuncID != -1) && (ParamCount != ProtoParamCount))
DieMessage("Invalid number of parameters in prototyped function", Symbols[FuncID].Name);
return ParamCount; return ParamCount;
} }
@ -45,7 +58,7 @@ static int ReadParameters() {
* //TODO: int i = 5; * //TODO: int i = 5;
* *
*/ */
void BeginVariableDeclaration(int Type, int Scope, bool isParameter) { void BeginVariableDeclaration(int Type, int Scope) {
int ID; int ID;
printf("type: %s\n", TypeNames[Type]); printf("type: %s\n", TypeNames[Type]);
@ -78,21 +91,35 @@ void BeginVariableDeclaration(int Type, int Scope, bool isParameter) {
struct ASTNode* ParseFunction(int Type) { struct ASTNode* ParseFunction(int Type) {
struct ASTNode* Tree; struct ASTNode* Tree;
struct ASTNode* FinalStatement; struct ASTNode* FinalStatement;
int SymbolSlot, BreakLabel, ParamCount; int SymbolSlot, BreakLabel, ParamCount, ID;
BreakLabel = NewLabel(); if((ID = FindSymbol(CurrentIdentifier)) != -1)
printf("\nIdentified function %s of return type %s, end label %d\n", CurrentIdentifier, TypeNames[Type], BreakLabel); if(Symbols[ID].Structure != ST_FUNC)
ID = -1;
SymbolSlot = AddSymbol(CurrentIdentifier, Type, ST_FUNC, SC_GLOBAL, BreakLabel, 1); printf("\nIdentified%sfunction %s of return type %s, end label %d\n", (ID == -1) ? " new " : " overloaded ", CurrentIdentifier, TypeNames[Type], BreakLabel);
CurrentFunction = SymbolSlot;
AsNewStackFrame(); if(ID == -1) {
SymbolSlot = AddSymbol(CurrentIdentifier, Type, ST_FUNC, SC_GLOBAL, BreakLabel, 1);
CurrentFunction = SymbolSlot;
BreakLabel = NewLabel();
}
VerifyToken(LI_LPARE, "("); VerifyToken(LI_LPARE, "(");
ParamCount = ReadParameters(); ParamCount = ReadParameters(ID);
Symbols[SymbolSlot].Length = ParamCount;
VerifyToken(LI_RPARE, ")"); VerifyToken(LI_RPARE, ")");
if(ID == -1) {
Symbols[SymbolSlot].Length = ParamCount;
ID = SymbolSlot;
}
if(CurrentToken.type == LI_SEMIC) {
Tokenise(&CurrentToken);
return NULL;
}
Tree = ParseCompound(); Tree = ParseCompound();
if(Type != RET_VOID) { if(Type != RET_VOID) {

26
tests/cat Normal file
View File

@ -0,0 +1,26 @@
int :: open(char* pathname, int flags);
int :: read(int fd, char* buffer, int size);
int :: write(int fd, void* buffer, int size);
int :: close(int fd);
char* textbuffer;
int :: main() {
int sourcefile;
int count;
textbuffer = " ";
sourcefile = open("tests/cat", 0);
if(sourcefile =? -1) {
return (1);
}
while((count = read(sourcefile, textbuffer, 60)) > 0) {
write(1, textbuffer, count);
}
close(sourcefile);
return (0);
}