Add function prototyping - we can now call cstdlib functions
This commit is contained in:
parent
813a6c7827
commit
52134784a4
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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",
|
||||||
|
|
27
src/Parser.c
27
src/Parser.c
|
@ -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)
|
||||||
|
|
|
@ -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
26
tests/cat
Normal 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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user