Big cleanup and fixes.

We have pointer arithmetic!
This commit is contained in:
Curle 2020-11-15 06:40:05 +00:00
parent d8abe6fec0
commit bc1bac8a63
Signed by: TheCurle
GPG Key ID: 2F2E62F0DA69A5AE
5 changed files with 145 additions and 65 deletions

View File

@ -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 * * * * * * * * 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 AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
int LeftVal, RightVal; int LeftVal, RightVal;
if(!Started)
DumpTree(Node, 0);
Started = 1;
printf("Current operation: %d\r\n", Node->Operation);
switch(Node->Operation) { switch(Node->Operation) {
case OP_IF: case OP_IF:
return AsIf(Node); return AsIf(Node);
@ -102,10 +107,18 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
return AsDeref(LeftVal, Node->Left->ExprType); return AsDeref(LeftVal, Node->Left->ExprType);
case OP_ASSIGN: 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: case OP_WIDEN:
return LeftVal; printf("\tWidening types..\r\n");
return LeftVal; //AsWiden(LeftVal, Node->Left->ExprType, Node->ExprType);
case OP_RET: case OP_RET:
AsReturn(LeftVal, CurrentFunction); AsReturn(LeftVal, CurrentFunction);
@ -146,14 +159,13 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
case REF_IDENT: case REF_IDENT:
return AsLdVar(Node->Value.ID); if(Node->RVal || ParentOp == OP_DEREF)
return AsLdVar(Node->Value.ID);
case LV_IDENT: else
return AsStrVar(Register, Node->Value.ID); return -1;
case TERM_INTLITERAL: case TERM_INTLITERAL:
return AsLoad(Node->Value.IntValue); return AsLoad(Node->Value.IntValue);
break;
case OP_PRINT: case OP_PRINT:
AssemblerPrint(LeftVal); AssemblerPrint(LeftVal);
@ -209,6 +221,7 @@ int NewLabel(void) {
static int id = 1; static int id = 1;
return id++; return id++;
} }
int AsIf(struct ASTNode* Node) { int AsIf(struct ASTNode* Node) {
int FalseLabel, EndLabel; int FalseLabel, EndLabel;
@ -439,11 +452,33 @@ int AsDeref(int Reg, int Type) {
case PTR_LONG: case PTR_LONG:
fprintf(OutputFile, "\tmovq\t(%s), %s\n", Registers[Reg], Registers[Reg]); fprintf(OutputFile, "\tmovq\t(%s), %s\n", Registers[Reg], Registers[Reg]);
break; break;
default:
DieDecimal("Can't generate dereference for type", Type);
} }
return Reg; 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) { void AsNewSymb(int ID) {
int TypeSize; int TypeSize;

View File

@ -77,6 +77,7 @@ int main(int argc, char* argv[]) {
} }
AddFunctionSymbol("PrintInteger", RET_CHAR, ST_FUNC, 0); AddFunctionSymbol("PrintInteger", RET_CHAR, ST_FUNC, 0);
//AddSymbol("forgecord", PTR_CHAR, ST_VAR);
Tokenise(&CurrentToken); Tokenise(&CurrentToken);

View File

@ -18,12 +18,12 @@
* *
*/ */
static int Precedence[] = static int Precedence[] =
{ 0, // EOF { 0, 10, // EOF, ASSIGN
10, 10, // + - 20, 20, // + -
20, 20, // * / 30, 30, // * /
30, 30, // =? != 40, 40, // =? !=
40, 40, // < > 50, 50, // < >
40, 40}; // <= => 50, 50}; // <= =>
static int OperatorPrecedence(int Token) { static int OperatorPrecedence(int Token) {
int Prec = Precedence[Token]; int Prec = Precedence[Token];
@ -35,6 +35,10 @@ static int OperatorPrecedence(int Token) {
return Prec; 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 * * * * * * 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; break;
default: default:
DieDecimal("Syntax Error", CurrentToken.type); DieDecimal("Unable to parse primary type", CurrentToken.type);
} }
Tokenise(&CurrentToken); Tokenise(&CurrentToken);
@ -147,77 +151,102 @@ struct ASTNode* ParsePrimary(void) {
struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) { struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
struct ASTNode* LeftNode, *RightNode; struct ASTNode* LeftNode, *RightNode;
struct ASTNode* LeftTemp, *RightTemp; struct ASTNode* LeftTemp, *RightTemp;
int LeftType, RightType; // int LeftType, RightType;
int NodeType, OpType; int NodeType, OpType;
LeftNode = PrefixStatement(); LeftNode = PrefixStatement();
NodeType = CurrentToken.type; NodeType = CurrentToken.type;
if(NodeType == LI_SEMIC || NodeType == LI_RPARE) if(NodeType == LI_SEMIC || NodeType == LI_RPARE) {
return LeftNode; LeftNode->RVal = 1; return LeftNode;
}
//printf("Current token has value %d, type %d\n", CurrentToken.value, CurrentToken.type);
while(OperatorPrecedence(NodeType) > PreviousTokenPrecedence) { 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"); //printf("inside while\n");
Tokenise(&CurrentToken); Tokenise(&CurrentToken);
RightNode = ParsePrecedenceASTNode(Precedence[NodeType]); RightNode = ParsePrecedenceASTNode(Precedence[NodeType]);
/*
LeftType = LeftNode->ExprType; LeftType = LeftNode->ExprType;
RightType = RightNode->ExprType; RightType = RightNode->ExprType;
*/
/** /**
* While parsing this node, we may need to widen some types. * While parsing this node, we may need to widen some types.
* This requires a few functions and checks. * This requires a few functions and checks.
*/ */
OpType = ParseTokenToOperation(NodeType); OpType = ParseTokenToOperation(NodeType);
LeftTemp = MutateType(LeftNode, RightType, OpType);
RightTemp = MutateType(RightNode, LeftType, OpType);
/** if(OpType == OP_ASSIGN) {
* If both are null, the types are incompatible. RightNode->RVal = 1;
*/
if(LeftTemp == NULL && RightTemp == NULL) RightNode = MutateType(RightNode, LeftNode->ExprType, 0);
Die("Incompatible types in parsing nodes"); 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));
/** LeftTemp = LeftNode;
* If the left was valid, or valid for LeftNode = RightNode;
* expansion, then it will be non-null. RightNode = LeftTemp;
* } else {
* If it was valid, then this will be LeftNode->RVal = 1;
* equivalent to LeftNode = LeftNode RightNode->RVal = 1;
*/
if(LeftTemp) printf("mutate left\r\n");
LeftNode = LeftTemp; 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
*/
/** if(LeftTemp)
* Same here, but there is a higher chance LeftNode = LeftTemp;
* for the right node to be incompatible due
* to the nature of widening types.
*/
if(RightTemp)
RightNode = RightTemp;
/**
* 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. * Checks over, back to normal parsing.
*/ */
/*
if(LeftType) if(LeftType)
LeftNode = ConstructASTBranch(LeftType, RightNode->ExprType, LeftNode, 0); LeftNode = ConstructASTBranch(LeftType, RightNode->ExprType, LeftNode, 0);
if(RightType) if(RightType)
RightNode = ConstructASTBranch(RightType, LeftNode->ExprType, RightNode, 0); RightNode = ConstructASTBranch(RightType, LeftNode->ExprType, RightNode, 0);
*/
LeftNode = ConstructASTNode(ParseTokenToOperation(NodeType), LeftNode->ExprType, LeftNode, NULL, RightNode, 0); LeftNode = ConstructASTNode(ParseTokenToOperation(NodeType), LeftNode->ExprType, LeftNode, NULL, RightNode, 0);
NodeType = CurrentToken.type; NodeType = CurrentToken.type;
if(NodeType == LI_SEMIC || NodeType == LI_RPARE) if(NodeType == LI_SEMIC || NodeType == LI_RPARE) {
LeftNode->RVal = 1;
return LeftNode; return LeftNode;
}
} }
LeftNode->RVal = 1;
return LeftNode; return LeftNode;
} }
@ -349,27 +378,23 @@ struct ASTNode* ParseStatement(void) {
int Type; int Type;
switch(CurrentToken.type) { switch(CurrentToken.type) {
case KW_PRINT:
return PrintStatement();
case TY_CHAR: case TY_CHAR:
case TY_LONG: case TY_LONG:
case TY_INT: case TY_INT:
printf("\t\tNew Variable: %s\n", CurrentIdentifier); printf("\t\tNew Variable: %s\n", CurrentIdentifier);
Type = ParseOptionalPointer(CurrentToken.type); Type = ParseOptionalPointer();
VerifyToken(TY_IDENTIFIER, "ident"); VerifyToken(TY_IDENTIFIER, "ident");
BeginVariableDeclaration(Type); BeginVariableDeclaration(Type);
return NULL; return NULL;
case TY_IDENTIFIER: /*case TY_IDENTIFIER:
if(Symbols[FindSymbol(CurrentIdentifier)].Structure == ST_FUNC) if(Symbols[FindSymbol(CurrentIdentifier)].Structure == ST_FUNC)
printf("\t\tCalling Function: %s\n", Symbols[FindSymbol(CurrentIdentifier)].Name); printf("\t\tCalling Function: %s\n", Symbols[FindSymbol(CurrentIdentifier)].Name);
else else
printf("\t\tAssigning variable: %s\n", Symbols[FindSymbol(CurrentIdentifier)].Name); printf("\t\tAssigning variable: %s\n", Symbols[FindSymbol(CurrentIdentifier)].Name);
return ParseIdentifier(); return ParseIdentifier();
*/
case KW_IF: case KW_IF:
return IfStatement(); return IfStatement();
@ -383,7 +408,8 @@ struct ASTNode* ParseStatement(void) {
return ReturnStatement(); return ReturnStatement();
default: default:
DieDecimal("Syntax Error in single-statement parsing. Token:", CurrentToken.type); ParsePrecedenceASTNode(0);
//DieDecimal("Syntax Error in single-statement parsing. Token:", CurrentToken.type);
} }
} }

View File

@ -101,17 +101,20 @@ struct ASTNode* ReturnStatement() {
Tree = ParsePrecedenceASTNode(0); Tree = ParsePrecedenceASTNode(0);
/*
ReturnType = Tree->ExprType; ReturnType = Tree->ExprType;
FunctionType = Symbols[CurrentFunction].Type; FunctionType = Symbols[CurrentFunction].Type;
*/
Tree = MutateType(Tree, FunctionType, 0); Tree = MutateType(Tree, Symbols[CurrentFunction].Type, 0);
if(!Tree) if(Tree == NULL)
Die("Returning a value of incorrect type for function"); Die("Returning a value of incorrect type for function");
/*
if(ReturnType) if(ReturnType)
Tree = ConstructASTBranch(ReturnType, FunctionType, Tree, 0); Tree = ConstructASTBranch(ReturnType, FunctionType, Tree, 0);
*/
Tree = ConstructASTBranch(OP_RET, RET_NONE, Tree, 0); Tree = ConstructASTBranch(OP_RET, RET_NONE, Tree, 0);
printf("\t\tReturning from function %s\n", Symbols[CurrentFunction].Name); printf("\t\tReturning from function %s\n", Symbols[CurrentFunction].Name);
@ -136,6 +139,7 @@ struct ASTNode* ReturnStatement() {
* *
*/ */
/*
struct ASTNode* ParseIdentifier() { struct ASTNode* ParseIdentifier() {
struct ASTNode* Left, *Right, *Tree; struct ASTNode* Left, *Right, *Tree;
int LeftType, RightType; int LeftType, RightType;
@ -171,7 +175,7 @@ struct ASTNode* ParseIdentifier() {
Tree = ConstructASTNode(OP_ASSIGN, RET_INT, Left, NULL, Right, 0); Tree = ConstructASTNode(OP_ASSIGN, RET_INT, Left, NULL, Right, 0);
return Tree; return Tree;
} }*/
struct ASTNode* IfStatement() { struct ASTNode* IfStatement() {
struct ASTNode* Condition, *True, *False = NULL; struct ASTNode* Condition, *True, *False = NULL;
@ -306,13 +310,13 @@ struct ASTNode* PrefixStatement() {
if(Tree->Operation != REF_IDENT && Tree->Operation != OP_DEREF) if(Tree->Operation != REF_IDENT && Tree->Operation != OP_DEREF)
Die("* must be followed by another * or an identifier."); Die("* must be followed by another * or an identifier.");
Tree = ConstructASTBranch(OP_DEREF, ValueAt(Tree->ExprType), Tree, 0); Tree = ConstructASTBranch(OP_DEREF, ValueAt(Tree->ExprType), Tree, 0);
break; break;
default: default:
Tree = ParsePrimary(); Tree = ParsePrimary();
} }
return Tree; return Tree;

14
tests/pointers2 Normal file
View File

@ -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);
}