Add new symbols to the parser. They are not currently handled

This commit is contained in:
Curle 2020-11-23 21:42:32 +00:00
parent e44158f3b7
commit 473af8d54e
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
4 changed files with 137 additions and 30 deletions

View File

@ -60,7 +60,7 @@ enum TokenTypes {
BOOL_INVERT, // Boolean Invert (!)
BIT_NOT, // Bitwise NOT (¬)
BIT_NOT, // Bitwise NOT (~)
LI_INT, // Integer literal
LI_STR, // String literal
@ -75,7 +75,6 @@ enum TokenTypes {
LI_LPARE, // (
LI_RPARE, // )
LI_AMP, // &
LI_COM, // ,
TY_IDENTIFIER, // Identifier name. Variable, function, etc.
@ -132,8 +131,10 @@ enum SyntaxOps {
OP_MULTIPLY, // Multiply two numbers.
OP_DIVIDE, // Divide two numbers.
OP_INCREMENT, // Increment a number (pre or postfix)
OP_DECREMENT, // Decrement a number (pre or postfix)
OP_PREINC, // Increment var before reference.
OP_PREDEC, // Decrement var before reference.
OP_POSTINC, // Increment var after reference.
OP_POSTDEC, // Decrement var after reference.
OP_BITNOT, // Invert a number bitwise
OP_BOOLNOT, // Invert a statement
@ -281,6 +282,7 @@ struct ASTNode* ParsePrimary(void);
//void ParseStatements(void);
struct ASTNode* ParseStatement(void);
struct ASTNode* PrefixStatement();
struct ASTNode* PostfixStatement();
void ParseGlobals();

View File

@ -243,11 +243,25 @@ int Tokenise(struct Token* Token) {
return 0;
case '+':
// + can be either "+" or "++".
Char = NextChar();
if(Char == '+') {
Token->type = PPMM_PLUS;
} else {
Token->type = AR_PLUS;
ReturnCharToStream(Char);
}
break;
case '-':
// - can be either "-" or "--"
Char = NextChar();
if(Char == '-') {
Token->type = PPMM_MINUS;
} else {
Token->type = AR_MINUS;
ReturnCharToStream(Char);
}
break;
case '*':
@ -259,7 +273,31 @@ int Tokenise(struct Token* Token) {
break;
case '&':
Token->type = LI_AMP;
Char = NextChar();
if(Char == '&') {
Token->type = BOOL_AND;
} else {
Token->type = BIT_AND;
ReturnCharToStream(Char);
}
break;
case '|':
Char = NextChar();
if(Char == '|') {
Token->type = BOOL_OR;
} else {
Token->type = BIT_OR;
ReturnCharToStream(Char);
}
break;
case '^':
Token->type = BIT_XOR;
break;
case '~':
Token->type = BIT_NOT;
break;
case ',':
@ -288,6 +326,7 @@ int Tokenise(struct Token* Token) {
Token->type = CMP_INEQ;
// Otherwise, we have a spare char
} else {
Token->type = BOOL_INVERT;
ReturnCharToStream(Char);
}
break;
@ -297,6 +336,8 @@ int Tokenise(struct Token* Token) {
// If the next char is =, we have <=, the less than or equal comparator.
if(Char == '=') {
Token->type = CMP_LTE;
} else if(Char == '<') { // But if the next char is <, we have << - the Shift Left operator.
Token->type = SH_LEFT;
} else {
ReturnCharToStream(Char);
Token->type = CMP_LT;
@ -304,8 +345,14 @@ int Tokenise(struct Token* Token) {
break;
case '>':
// There is no special casing for >. Less than or equal is =>
// For >, Less than or equal is => so we can ignore it, but the Shift Right operator is >>.
Char = NextChar();
if(Char == '>') {
Token->type = SH_RIGHT;
} else {
Token->type = CMP_GT;
ReturnCharToStream(Char);
}
break;
case ';':

View File

@ -128,26 +128,7 @@ struct ASTNode* ParsePrimary(void) {
break;
case TY_IDENTIFIER:
// A variable or a function?
// Read the next token
Tokenise(&CurrentToken);
// If the token after the identifier is a (, then it's a function.
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)
DieMessage("Unknown Variable", CurrentIdentifier);
Node = ConstructASTLeaf(REF_IDENT, Symbols[ID].Type, ID);
break;
return PostfixStatement();
case LI_RPARE:
// Starting a ( expr ) block

View File

@ -301,11 +301,88 @@ struct ASTNode* PrintStatement(void) {
}
struct ASTNode* PostfixStatement() {
struct ASTNode* Tree;
int ID;
Tokenise(&CurrentToken);
// If we get here, we're one of three things:
// - Function
// - Array
// - Variable
if(CurrentToken.type == LI_LPARE)
return CallFunction();
if(CurrentToken.type == LI_LBRAS)
return AccessArray();
// If we get here, we must be a variable.
// There's no guarantees that the variable is in
// the symbol table, though.
ID = FindSymbol(CurrentIdentifier);
if(ID == -1 || Symbols[ID].Structure != ST_VAR)
DieMessage("Unknown Variable", CurrentIdentifier);
// Here we check for postincrement and postdecrement.
switch(CurrentToken.type) {
case PPMM_PLUS:
Tokenise(&CurrentToken);
Tree = ConstructASTLeaf(OP_POSTINC, Symbols[ID].Type, ID);
break;
case PPMM_MINUS:
Tokenise(&CurrentToken);
Tree = ConstructASTLeaf(OP_POSTDEC, Symbols[ID].Type, ID);
break;
default:
Tree = ConstructASTLeaf(REF_IDENT, Symbols[ID].Type, ID);
}
return Tree;
}
struct ASTNode* PrefixStatement() {
struct ASTNode* Tree;
switch (CurrentToken.type) {
case LI_AMP:
case BOOL_INVERT:
Tokenise(&CurrentToken);
Tree = PrefixStatement();
Tree->RVal = 1;
Tree = ConstructASTBranch(OP_BOOLNOT, Tree->ExprType, Tree, 0);
break;
case BIT_NOT:
Tokenise(&CurrentToken);
Tree = PrefixStatement();
Tree->RVal = 1;
Tree = ConstructASTBranch(OP_BITNOT, Tree->ExprType, Tree, 0);
break;
case PPMM_PLUS:
Tokenise(&CurrentToken);
Tree = PrefixStatement();
if(Tree->Operation != REF_IDENT)
Die("++ not followed by identifier");
Tree = ConstructASTBranch(OP_PREINC, Tree->ExprType, Tree, 0);
break;
case PPMM_MINUS:
Tokenise(&CurrentToken);
Tree = PrefixStatement();
if(Tree->Operation != REF_IDENT)
Die("-- not followed by identifier");
Tree = ConstructASTBranch(OP_PREDEC, Tree->ExprType, Tree, 0);
break;
case BIT_AND:
Tokenise(&CurrentToken);
// To allow things like: