diff --git a/src/Assembler.c b/src/Assembler.c index 3f9051a..a63a941 100644 --- a/src/Assembler.c +++ b/src/Assembler.c @@ -30,10 +30,15 @@ static char* InvComparisons[6] = { "jne", "je", "jge", "jle", "jg", "j * * * * R O O T O F A S S E M B L E R * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +static int Started = 0; int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) { int LeftVal, RightVal; + if(!Started) + DumpTree(Node, 0); + Started = 1; + printf("Current operation: %d\r\n", Node->Operation); switch(Node->Operation) { case OP_IF: return AsIf(Node); @@ -102,10 +107,18 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) { return AsDeref(LeftVal, Node->Left->ExprType); case OP_ASSIGN: - return RightVal; + printf("Calculating for assignment..\r\n"); + if(Node->Right == NULL) + Die("Fault in assigning a null rvalue"); + switch(Node->Right->Operation) { + case REF_IDENT: return AsStrVar(LeftVal, Node->Right->Value.ID); + case OP_DEREF: return AsStrDeref(LeftVal, RightVal, Node->Right->ExprType); + default: DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation); + } case OP_WIDEN: - return LeftVal; + printf("\tWidening types..\r\n"); + return LeftVal; //AsWiden(LeftVal, Node->Left->ExprType, Node->ExprType); case OP_RET: AsReturn(LeftVal, CurrentFunction); @@ -146,14 +159,13 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) { case REF_IDENT: - return AsLdVar(Node->Value.ID); - - case LV_IDENT: - return AsStrVar(Register, Node->Value.ID); + if(Node->RVal || ParentOp == OP_DEREF) + return AsLdVar(Node->Value.ID); + else + return -1; case TERM_INTLITERAL: return AsLoad(Node->Value.IntValue); - break; case OP_PRINT: AssemblerPrint(LeftVal); @@ -209,6 +221,7 @@ int NewLabel(void) { static int id = 1; return id++; } + int AsIf(struct ASTNode* Node) { int FalseLabel, EndLabel; @@ -439,11 +452,33 @@ int AsDeref(int Reg, int Type) { case PTR_LONG: fprintf(OutputFile, "\tmovq\t(%s), %s\n", Registers[Reg], Registers[Reg]); break; + default: + DieDecimal("Can't generate dereference for type", Type); } return Reg; } +int AsStrDeref(int Register1, int Register2, int Type) { + printf("\tStoring contents of %s into %s through a dereference, type %d\n", Registers[Register1], Registers[Register2], Type); + + switch(Type) { + case PTR_CHAR: + fprintf(OutputFile, "\tmovb\t%s, (%s)\n", ByteRegisters[Register1], Registers[Register2]); + break; + case PTR_INT: + fprintf(OutputFile, "\tmovq\t%s, (%s)\n", Registers[Register1], Registers[Register2]); + break; + case PTR_LONG: + fprintf(OutputFile, "\tmovq\t%s, (%s)\n", Registers[Register1], Registers[Register2]); + break; + default: + DieDecimal("Can't generate store-into-deref of type", Type); + } + + return Register1; +} + void AsNewSymb(int ID) { int TypeSize; diff --git a/src/Main.c b/src/Main.c index db97ac8..edda6ab 100644 --- a/src/Main.c +++ b/src/Main.c @@ -77,6 +77,7 @@ int main(int argc, char* argv[]) { } AddFunctionSymbol("PrintInteger", RET_CHAR, ST_FUNC, 0); + //AddSymbol("forgecord", PTR_CHAR, ST_VAR); Tokenise(&CurrentToken); diff --git a/src/Parser.c b/src/Parser.c index ffbd2a2..38f94ed 100644 --- a/src/Parser.c +++ b/src/Parser.c @@ -18,12 +18,12 @@ * */ static int Precedence[] = - { 0, // EOF - 10, 10, // + - - 20, 20, // * / - 30, 30, // =? != - 40, 40, // < > - 40, 40}; // <= => + { 0, 10, // EOF, ASSIGN + 20, 20, // + - + 30, 30, // * / + 40, 40, // =? != + 50, 50, // < > + 50, 50}; // <= => static int OperatorPrecedence(int Token) { int Prec = Precedence[Token]; @@ -35,6 +35,10 @@ static int OperatorPrecedence(int Token) { return Prec; } +static int IsRightExpr(int Token) { + return (Token == LI_EQUAL); +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * N O D E C O N S T R U C T I O N * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -135,7 +139,7 @@ struct ASTNode* ParsePrimary(void) { break; default: - DieDecimal("Syntax Error", CurrentToken.type); + DieDecimal("Unable to parse primary type", CurrentToken.type); } Tokenise(&CurrentToken); @@ -147,77 +151,102 @@ struct ASTNode* ParsePrimary(void) { struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) { struct ASTNode* LeftNode, *RightNode; struct ASTNode* LeftTemp, *RightTemp; - int LeftType, RightType; + // int LeftType, RightType; int NodeType, OpType; LeftNode = PrefixStatement(); NodeType = CurrentToken.type; - if(NodeType == LI_SEMIC || NodeType == LI_RPARE) - return LeftNode; - - //printf("Current token has value %d, type %d\n", CurrentToken.value, CurrentToken.type); - while(OperatorPrecedence(NodeType) > PreviousTokenPrecedence) { + if(NodeType == LI_SEMIC || NodeType == LI_RPARE) { + LeftNode->RVal = 1; return LeftNode; + } + + printf("Current token has value %d, type %d\n", CurrentToken.value, CurrentToken.type); + while((OperatorPrecedence(NodeType) > PreviousTokenPrecedence) || (IsRightExpr(OpType) && OperatorPrecedence(OpType) == PreviousTokenPrecedence)) { //printf("inside while\n"); Tokenise(&CurrentToken); RightNode = ParsePrecedenceASTNode(Precedence[NodeType]); + /* LeftType = LeftNode->ExprType; RightType = RightNode->ExprType; - + */ /** * While parsing this node, we may need to widen some types. * This requires a few functions and checks. */ OpType = ParseTokenToOperation(NodeType); - LeftTemp = MutateType(LeftNode, RightType, OpType); - RightTemp = MutateType(RightNode, LeftType, OpType); - /** - * If both are null, the types are incompatible. - */ + if(OpType == OP_ASSIGN) { + RightNode->RVal = 1; - if(LeftTemp == NULL && RightTemp == NULL) - Die("Incompatible types in parsing nodes"); + RightNode = MutateType(RightNode, LeftNode->ExprType, 0); + if(LeftNode == NULL) + Die("Incompatible Expression encountered in assignment"); + + printf("\tAssigning variable: %s\n", Symbols[FindSymbol(CurrentIdentifier)].Name); + printf("\tAfter parsing, the identifier name is %s, id %d in the symbol table.\n", CurrentIdentifier, FindSymbol(CurrentIdentifier)); - /** - * If the left was valid, or valid for - * expansion, then it will be non-null. - * - * If it was valid, then this will be - * equivalent to LeftNode = LeftNode - */ + LeftTemp = LeftNode; + LeftNode = RightNode; + RightNode = LeftTemp; + } else { + LeftNode->RVal = 1; + RightNode->RVal = 1; - if(LeftTemp) - LeftNode = LeftTemp; + printf("mutate left\r\n"); + LeftTemp = MutateType(LeftNode, RightNode->ExprType, OpType); + printf("mutate right\r\n"); + RightTemp = MutateType(RightNode, LeftNode->ExprType, OpType); + printf("mutate right over\r\n"); + /** + * If both are null, the types are incompatible. + */ + + if(LeftTemp == NULL && RightTemp == NULL) + Die("Incompatible types in parsing nodes"); + + /** + * If the left was valid, or valid for + * expansion, then it will be non-null. + * + * If it was valid, then this will be + * equivalent to LeftNode = LeftNode + */ - /** - * Same here, but there is a higher chance - * for the right node to be incompatible due - * to the nature of widening types. - */ - - if(RightTemp) - RightNode = RightTemp; + if(LeftTemp) + LeftNode = LeftTemp; + /** + * Same here, but there is a higher chance + * for the right node to be incompatible due + * to the nature of widening types. + */ + + if(RightTemp) + RightNode = RightTemp; + } + /** * Checks over, back to normal parsing. */ - + /* if(LeftType) LeftNode = ConstructASTBranch(LeftType, RightNode->ExprType, LeftNode, 0); if(RightType) RightNode = ConstructASTBranch(RightType, LeftNode->ExprType, RightNode, 0); - + */ LeftNode = ConstructASTNode(ParseTokenToOperation(NodeType), LeftNode->ExprType, LeftNode, NULL, RightNode, 0); - NodeType = CurrentToken.type; - if(NodeType == LI_SEMIC || NodeType == LI_RPARE) + if(NodeType == LI_SEMIC || NodeType == LI_RPARE) { + LeftNode->RVal = 1; return LeftNode; + } + } - + LeftNode->RVal = 1; return LeftNode; } @@ -349,27 +378,23 @@ struct ASTNode* ParseStatement(void) { int Type; switch(CurrentToken.type) { - - case KW_PRINT: - return PrintStatement(); - case TY_CHAR: case TY_LONG: case TY_INT: printf("\t\tNew Variable: %s\n", CurrentIdentifier); - Type = ParseOptionalPointer(CurrentToken.type); + Type = ParseOptionalPointer(); VerifyToken(TY_IDENTIFIER, "ident"); BeginVariableDeclaration(Type); return NULL; - case TY_IDENTIFIER: + /*case TY_IDENTIFIER: if(Symbols[FindSymbol(CurrentIdentifier)].Structure == ST_FUNC) printf("\t\tCalling Function: %s\n", Symbols[FindSymbol(CurrentIdentifier)].Name); else printf("\t\tAssigning variable: %s\n", Symbols[FindSymbol(CurrentIdentifier)].Name); return ParseIdentifier(); - + */ case KW_IF: return IfStatement(); @@ -383,7 +408,8 @@ struct ASTNode* ParseStatement(void) { return ReturnStatement(); default: - DieDecimal("Syntax Error in single-statement parsing. Token:", CurrentToken.type); + ParsePrecedenceASTNode(0); + //DieDecimal("Syntax Error in single-statement parsing. Token:", CurrentToken.type); } } diff --git a/src/Statements.c b/src/Statements.c index dfaa7be..da311f3 100644 --- a/src/Statements.c +++ b/src/Statements.c @@ -101,17 +101,20 @@ struct ASTNode* ReturnStatement() { Tree = ParsePrecedenceASTNode(0); + /* ReturnType = Tree->ExprType; FunctionType = Symbols[CurrentFunction].Type; + */ - Tree = MutateType(Tree, FunctionType, 0); - if(!Tree) + Tree = MutateType(Tree, Symbols[CurrentFunction].Type, 0); + if(Tree == NULL) Die("Returning a value of incorrect type for function"); - + /* if(ReturnType) Tree = ConstructASTBranch(ReturnType, FunctionType, Tree, 0); - + */ + Tree = ConstructASTBranch(OP_RET, RET_NONE, Tree, 0); printf("\t\tReturning from function %s\n", Symbols[CurrentFunction].Name); @@ -136,6 +139,7 @@ struct ASTNode* ReturnStatement() { * */ +/* struct ASTNode* ParseIdentifier() { struct ASTNode* Left, *Right, *Tree; int LeftType, RightType; @@ -171,7 +175,7 @@ struct ASTNode* ParseIdentifier() { Tree = ConstructASTNode(OP_ASSIGN, RET_INT, Left, NULL, Right, 0); return Tree; -} +}*/ struct ASTNode* IfStatement() { struct ASTNode* Condition, *True, *False = NULL; @@ -306,13 +310,13 @@ struct ASTNode* PrefixStatement() { if(Tree->Operation != REF_IDENT && Tree->Operation != OP_DEREF) Die("* must be followed by another * or an identifier."); - + Tree = ConstructASTBranch(OP_DEREF, ValueAt(Tree->ExprType), Tree, 0); break; default: Tree = ParsePrimary(); - + } return Tree; diff --git a/tests/pointers2 b/tests/pointers2 new file mode 100644 index 0000000..b5dabb1 --- /dev/null +++ b/tests/pointers2 @@ -0,0 +1,14 @@ +int c; +int d; +int *e; +int f; + +int :: main() { + c= 12; + d=18; + PrintInteger(c); + e= &c + 1; + f= *e; + PrintInteger(f); + return(0); +}