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 * * * *
* * * * * * * * * * * * * * * * * * * * * * */
void BeginVariableDeclaration(int Type, int Scope, bool isParameter);
void BeginVariableDeclaration(int Type, int Scope);
struct ASTNode* ParseIdentifier(void);
struct ASTNode* IfStatement();

View File

@ -179,6 +179,7 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
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(Symbols[Node->Value.ID].Storage == SC_LOCAL || Symbols[Node->Value.ID].Storage == SC_PARAM)
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
char* TokenNames[] = {
"", // Push everything up by one
"End of file",
"Equivalency",
@ -46,6 +45,7 @@ char* TokenNames[] = {
"Bitwise Invert",
"Integer literal",
"String literal",
"Statement End",
"Compound Block Start",
@ -56,8 +56,7 @@ char* TokenNames[] = {
"Logical Block Start",
"Logical Block End",
"Dereference operator",
"Comma",
"Identifier",

View File

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

View File

@ -8,14 +8,24 @@
#include <Data.h>
#include <stdbool.h>
static int ReadParameters() {
int TokenType, ParamCount = 0;
static int ReadParameters(int FuncID) {
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) {
TokenType = ParseOptionalPointer();
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++;
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;
}
@ -45,7 +58,7 @@ static int ReadParameters() {
* //TODO: int i = 5;
*
*/
void BeginVariableDeclaration(int Type, int Scope, bool isParameter) {
void BeginVariableDeclaration(int Type, int Scope) {
int ID;
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* Tree;
struct ASTNode* FinalStatement;
int SymbolSlot, BreakLabel, ParamCount;
int SymbolSlot, BreakLabel, ParamCount, ID;
BreakLabel = NewLabel();
printf("\nIdentified function %s of return type %s, end label %d\n", CurrentIdentifier, TypeNames[Type], BreakLabel);
if((ID = FindSymbol(CurrentIdentifier)) != -1)
if(Symbols[ID].Structure != ST_FUNC)
ID = -1;
printf("\nIdentified%sfunction %s of return type %s, end label %d\n", (ID == -1) ? " new " : " overloaded ", CurrentIdentifier, TypeNames[Type], BreakLabel);
SymbolSlot = AddSymbol(CurrentIdentifier, Type, ST_FUNC, SC_GLOBAL, BreakLabel, 1);
CurrentFunction = SymbolSlot;
AsNewStackFrame();
if(ID == -1) {
SymbolSlot = AddSymbol(CurrentIdentifier, Type, ST_FUNC, SC_GLOBAL, BreakLabel, 1);
CurrentFunction = SymbolSlot;
BreakLabel = NewLabel();
}
VerifyToken(LI_LPARE, "(");
ParamCount = ReadParameters();
Symbols[SymbolSlot].Length = ParamCount;
ParamCount = ReadParameters(ID);
VerifyToken(LI_RPARE, ")");
if(ID == -1) {
Symbols[SymbolSlot].Length = ParamCount;
ID = SymbolSlot;
}
if(CurrentToken.type == LI_SEMIC) {
Tokenise(&CurrentToken);
return NULL;
}
Tree = ParseCompound();
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);
}