Begin cleanup of array parsing

TODO: debug segfault
This commit is contained in:
Curle 2020-11-19 02:31:40 +00:00
parent 985f02723e
commit 999f8dc267
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
5 changed files with 62 additions and 24 deletions

View File

@ -257,6 +257,7 @@ int ParseOptionalPointer();
int ValueAt(int Type);
int PointerTo(int Type);
struct ASTNode* AccessArray();
int ParseTokenToOperation(int Token);

View File

@ -15,6 +15,7 @@ int TypeSizes[9] = { 0, 1, 4, 8, 0, 8, 8,
char* TokenStrings[] = { "+", "-", "*", "/", "int" };
char* TokenNames[] = {
"End of file",
"Equivalency",
"Addition",
"Subtraction",
@ -28,17 +29,20 @@ char* TokenNames[] = {
"Less Than or Equal",
"Greater Than or Equal",
"Assignment",
"Integer literal",
"Statement End",
"Compound Block Start",
"Compound Block End",
"Array index start",
"Array index end",
"Logical Block Start",
"Logical Block End",
"Dereference operator",
"Comma",
"Identifier",
"None Type",
@ -103,16 +107,16 @@ void Die(char* Error) {
}
void DieMessage(char* Error, char* Reason) {
fprintf(stderr, "%s:%s on line %d\n", Error, Reason, Line);
fprintf(stderr, "%s: %s on line %d\n", Error, Reason, Line);
exit(1);
}
void DieDecimal(char* Error, int Number) {
fprintf(stderr, "%s:%d on line %d\n", Error, Number, Line);
fprintf(stderr, "%s: %d on line %d\n", Error, Number, Line);
exit(1);
}
void DieChar(char* Error, int Char) {
fprintf(stderr, "%s:%c on line %d\n", Error, Char, Line);
fprintf(stderr, "%s: %c on line %d\n", Error, Char, Line);
exit(1);
}

View File

@ -28,8 +28,8 @@ static int Precedence[] =
static int OperatorPrecedence(int Token) {
int Prec = Precedence[Token];
if(Prec == 0) {
Die("Attempting to determine operator precedence of an EOF or INT literal.");
if(Prec == 0 || Token >= RET_VOID) {
DieMessage("Attempting to determine operator precedence of an EOF or INT literal", TokenNames[Token]);
}
return Prec;
@ -114,8 +114,6 @@ struct ASTNode* ParsePrimary(void) {
Node = ConstructASTLeaf(TERM_INTLITERAL, RET_CHAR, CurrentToken.value);
else
Node = ConstructASTLeaf(TERM_INTLITERAL, RET_INT, CurrentToken.value);
//Tokenise(&CurrentToken); // Fetch next token
break;
case TY_IDENTIFIER:
@ -128,9 +126,11 @@ struct ASTNode* ParsePrimary(void) {
if(CurrentToken.type == LI_LPARE)
return CallFunction();
if(CurrentToken.type == LI_LBRAS)
return AccessArray();
// Otherwise, we've read too far and need to go back.
RejectToken(&CurrentToken);
// It's a variable, so find the symbol and construct a leaf for it
ID = FindSymbol(CurrentIdentifier);
if(ID == -1)
@ -138,24 +138,18 @@ struct ASTNode* ParsePrimary(void) {
Node = ConstructASTLeaf(REF_IDENT, Symbols[ID].Type, ID);
break;
case LI_LPARE:
// We're expecting a primary encased in parentheses.
// That means, we tokenise the next item
case LI_RPARE:
// Starting a ( expr ) block
Tokenise(&CurrentToken);
// Then, we expect a valid expression
Node = ParsePrecedenceASTNode(0);
// Then, after the expression is parsed, we're returned here.
// since the expression is ENCASED in parens, we expect another.
// Make sure we close
VerifyToken(LI_RPARE, ")");
// Skip the next tokenise and return early
return Node;
default:
DieDecimal("Unable to parse primary type", CurrentToken.type);
}
Tokenise(&CurrentToken);
return Node;
@ -171,11 +165,13 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
LeftNode = PrefixStatement();
NodeType = CurrentToken.type;
if(NodeType == LI_SEMIC || NodeType == LI_RPARE) {
printf("%d\r\n", CurrentToken.type);
if(NodeType == LI_SEMIC || NodeType == LI_RPARE || NodeType == LI_RBRAS) {
printf("Current token matches ; ) ]\r\n");
LeftNode->RVal = 1; return LeftNode;
}
printf("Current token has value %d, type %d\n", CurrentToken.value, CurrentToken.type);
printf("Current token has value %d, type %s\n", CurrentToken.value, TokenNames[CurrentToken.type]);
while((OperatorPrecedence(NodeType) > PreviousTokenPrecedence) || (IsRightExpr(OpType) && OperatorPrecedence(OpType) == PreviousTokenPrecedence)) {
//printf("inside while\n");
Tokenise(&CurrentToken);
@ -254,7 +250,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
*/
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 || NodeType == LI_RBRAS) {
LeftNode->RVal = 1;
return LeftNode;
}

View File

@ -65,3 +65,30 @@ int ParseOptionalPointer() {
return Type;
}
struct ASTNode* AccessArray() {
struct ASTNode* LeftNode, *RightNode;
int ID;
printf("\tAccessing array %s as requested\r\n", CurrentIdentifier);
if ((ID = FindSymbol(CurrentIdentifier)) == -1 || Symbols[ID].Structure != ST_ARR)
DieMessage("Accessing undeclared array", CurrentIdentifier);
LeftNode = ConstructASTLeaf(OP_ADDRESS, Symbols[ID].Type, ID);
printf("\t\tCurrent token: %s\r\n", TokenNames[CurrentToken.type]);
Tokenise(&CurrentToken);
printf("\t\tCurrent token: %s\r\n", TokenNames[CurrentToken.type]);
RightNode = ParsePrecedenceASTNode(0);
VerifyToken(LI_RBRAS, "]");
if(!TypeIsInt(RightNode->ExprType))
Die("Array index is not integer");
RightNode = MutateType(RightNode, LeftNode->ExprType, OP_ADD);
LeftNode = ConstructASTNode(OP_ADD, Symbols[ID].Type, LeftNode, NULL, RightNode, 0);
LeftNode = ConstructASTBranch(OP_DEREF, ValueAt(LeftNode->ExprType), LeftNode, 0);
return LeftNode;
}

10
tests/arrays1 Normal file
View File

@ -0,0 +1,10 @@
int a;
int b[25];
int :: main() {
b[3] = 12;
a = b[3];
PrintInteger(a);
PrintInteger(b[5]);
return(0);
}