Add new symbols to the parser. They are not currently handled
This commit is contained in:
parent
e44158f3b7
commit
473af8d54e
|
@ -60,7 +60,7 @@ enum TokenTypes {
|
||||||
|
|
||||||
BOOL_INVERT, // Boolean Invert (!)
|
BOOL_INVERT, // Boolean Invert (!)
|
||||||
|
|
||||||
BIT_NOT, // Bitwise NOT (¬)
|
BIT_NOT, // Bitwise NOT (~)
|
||||||
|
|
||||||
LI_INT, // Integer literal
|
LI_INT, // Integer literal
|
||||||
LI_STR, // String literal
|
LI_STR, // String literal
|
||||||
|
@ -75,7 +75,6 @@ enum TokenTypes {
|
||||||
LI_LPARE, // (
|
LI_LPARE, // (
|
||||||
LI_RPARE, // )
|
LI_RPARE, // )
|
||||||
|
|
||||||
LI_AMP, // &
|
|
||||||
LI_COM, // ,
|
LI_COM, // ,
|
||||||
|
|
||||||
TY_IDENTIFIER, // Identifier name. Variable, function, etc.
|
TY_IDENTIFIER, // Identifier name. Variable, function, etc.
|
||||||
|
@ -132,8 +131,10 @@ enum SyntaxOps {
|
||||||
OP_MULTIPLY, // Multiply two numbers.
|
OP_MULTIPLY, // Multiply two numbers.
|
||||||
OP_DIVIDE, // Divide two numbers.
|
OP_DIVIDE, // Divide two numbers.
|
||||||
|
|
||||||
OP_INCREMENT, // Increment a number (pre or postfix)
|
OP_PREINC, // Increment var before reference.
|
||||||
OP_DECREMENT, // Decrement a number (pre or postfix)
|
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_BITNOT, // Invert a number bitwise
|
||||||
OP_BOOLNOT, // Invert a statement
|
OP_BOOLNOT, // Invert a statement
|
||||||
|
@ -281,6 +282,7 @@ struct ASTNode* ParsePrimary(void);
|
||||||
//void ParseStatements(void);
|
//void ParseStatements(void);
|
||||||
struct ASTNode* ParseStatement(void);
|
struct ASTNode* ParseStatement(void);
|
||||||
struct ASTNode* PrefixStatement();
|
struct ASTNode* PrefixStatement();
|
||||||
|
struct ASTNode* PostfixStatement();
|
||||||
|
|
||||||
void ParseGlobals();
|
void ParseGlobals();
|
||||||
|
|
||||||
|
|
57
src/Lexer.c
57
src/Lexer.c
|
@ -243,11 +243,25 @@ int Tokenise(struct Token* Token) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case '+':
|
case '+':
|
||||||
Token->type = AR_PLUS;
|
// + can be either "+" or "++".
|
||||||
|
Char = NextChar();
|
||||||
|
if(Char == '+') {
|
||||||
|
Token->type = PPMM_PLUS;
|
||||||
|
} else {
|
||||||
|
Token->type = AR_PLUS;
|
||||||
|
ReturnCharToStream(Char);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
Token->type = AR_MINUS;
|
// - can be either "-" or "--"
|
||||||
|
Char = NextChar();
|
||||||
|
if(Char == '-') {
|
||||||
|
Token->type = PPMM_MINUS;
|
||||||
|
} else {
|
||||||
|
Token->type = AR_MINUS;
|
||||||
|
ReturnCharToStream(Char);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
|
@ -259,7 +273,31 @@ int Tokenise(struct Token* Token) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '&':
|
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;
|
break;
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
|
@ -288,6 +326,7 @@ int Tokenise(struct Token* Token) {
|
||||||
Token->type = CMP_INEQ;
|
Token->type = CMP_INEQ;
|
||||||
// Otherwise, we have a spare char
|
// Otherwise, we have a spare char
|
||||||
} else {
|
} else {
|
||||||
|
Token->type = BOOL_INVERT;
|
||||||
ReturnCharToStream(Char);
|
ReturnCharToStream(Char);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -297,6 +336,8 @@ int Tokenise(struct Token* Token) {
|
||||||
// If the next char is =, we have <=, the less than or equal comparator.
|
// If the next char is =, we have <=, the less than or equal comparator.
|
||||||
if(Char == '=') {
|
if(Char == '=') {
|
||||||
Token->type = CMP_LTE;
|
Token->type = CMP_LTE;
|
||||||
|
} else if(Char == '<') { // But if the next char is <, we have << - the Shift Left operator.
|
||||||
|
Token->type = SH_LEFT;
|
||||||
} else {
|
} else {
|
||||||
ReturnCharToStream(Char);
|
ReturnCharToStream(Char);
|
||||||
Token->type = CMP_LT;
|
Token->type = CMP_LT;
|
||||||
|
@ -304,8 +345,14 @@ int Tokenise(struct Token* Token) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>':
|
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 >>.
|
||||||
Token->type = CMP_GT;
|
Char = NextChar();
|
||||||
|
if(Char == '>') {
|
||||||
|
Token->type = SH_RIGHT;
|
||||||
|
} else {
|
||||||
|
Token->type = CMP_GT;
|
||||||
|
ReturnCharToStream(Char);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ';':
|
case ';':
|
||||||
|
|
21
src/Parser.c
21
src/Parser.c
|
@ -128,26 +128,7 @@ struct ASTNode* ParsePrimary(void) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TY_IDENTIFIER:
|
case TY_IDENTIFIER:
|
||||||
// A variable or a function?
|
return PostfixStatement();
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
case LI_RPARE:
|
case LI_RPARE:
|
||||||
// Starting a ( expr ) block
|
// Starting a ( expr ) block
|
||||||
|
|
|
@ -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* PrefixStatement() {
|
||||||
struct ASTNode* Tree;
|
struct ASTNode* Tree;
|
||||||
|
|
||||||
switch (CurrentToken.type) {
|
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);
|
Tokenise(&CurrentToken);
|
||||||
|
|
||||||
// To allow things like:
|
// To allow things like:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user