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 * * * *
|
||||
* * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
void BeginVariableDeclaration(int Type, int Scope, bool isParameter);
|
||||
void BeginVariableDeclaration(int Type, int Scope);
|
||||
struct ASTNode* ParseIdentifier(void);
|
||||
|
||||
struct ASTNode* IfStatement();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
@ -57,7 +57,6 @@ char* TokenNames[] = {
|
|||
"Logical Block Start",
|
||||
"Logical Block End",
|
||||
|
||||
"Dereference operator",
|
||||
"Comma",
|
||||
|
||||
"Identifier",
|
||||
|
|
27
src/Parser.c
27
src/Parser.c
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
SymbolSlot = AddSymbol(CurrentIdentifier, Type, ST_FUNC, SC_GLOBAL, BreakLabel, 1);
|
||||
CurrentFunction = SymbolSlot;
|
||||
printf("\nIdentified%sfunction %s of return type %s, end label %d\n", (ID == -1) ? " new " : " overloaded ", CurrentIdentifier, TypeNames[Type], BreakLabel);
|
||||
|
||||
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
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