56 minutes ago, SlithyMatt said:
Yep, but the math expression parsing will require a bit more introspection to break it down. Would be a lot easier if it was something like Forth, as that is closer to how computers actually work.
#define PREC_NONE 0
#define PREC_ASSIGNMENT 1
#define PREC_OR 2
#define PREC_AND 3
#define PREC_EQUALITY 4
#define PREC_COMPARISON 5
#define PREC_TERM 6
#define PREC_FACTOR 7
#define PREC_UNARY 8
#define PREC_CALL 9
#define PREC_PRIMARY 10
[...later...]
//
// Pratt Parser data.
//
// typedef uint8_t ParseRuleNum;
// ParseFn prefix[MAX_TOKEN_VALUE];
// ParseFn infix[MAX_TOKEN_VALUE];
// Precedence precedence[MAX_TOKEN_VALUE];
//
// prefixRule[ num ] = NULL | grouping | unary | number
// infixRule[ num ] = NULL | binary
// precedence[ num ] = PREC_NONE | PREC_FACTOR
//
#define ParseRule(n,pf,if,prec) prefixRule[n]=pf;infixRule[n]=if;precedenceRule[n]=prec
void initPrattTable()
{
ParseRule(TOKEN_RIGHT_PAREN ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_LEFT_BRACE ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_RIGHT_BRACE ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_COMMA ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_DOT ,NULL, binary,PREC_TERM);
ParseRule(TOKEN_MINUS ,unary, binary,PREC_TERM);
ParseRule(TOKEN_PLUS ,NULL, binary,PREC_TERM);
ParseRule(TOKEN_SEMICOLON ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_SLASH ,NULL, binary,PREC_FACTOR);
ParseRule(TOKEN_MOD ,NULL, binary,PREC_FACTOR);
ParseRule(TOKEN_STAR ,NULL, binary,PREC_FACTOR);
ParseRule(TOKEN_UP ,NULL, binary,PREC_FACTOR);
ParseRule(TOKEN_BANG ,unary, NULL, PREC_NONE);
ParseRule(TOKEN_BANG_EQUAL ,NULL, binary, PREC_EQUALITY);
ParseRule(TOKEN_EQUAL ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_EQUAL_EQUAL ,NULL, binary, PREC_EQUALITY);
ParseRule(TOKEN_GREATER ,NULL, binary, PREC_EQUALITY);
ParseRule(TOKEN_GREATER_EQUAL,NULL, binary, PREC_EQUALITY);
ParseRule(TOKEN_LESS ,NULL, binary, PREC_EQUALITY);
ParseRule(TOKEN_LESS_EQUAL ,NULL, binary, PREC_EQUALITY);
ParseRule(TOKEN_IDENTIFIER ,variable,NULL, PREC_NONE);
ParseRule(TOKEN_STRING ,string, NULL, PREC_NONE);
ParseRule(TOKEN_NUMBER ,number, NULL, PREC_NONE);
ParseRule(TOKEN_AND ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_ELSE ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_FALSE ,literal, NULL, PREC_NONE);
ParseRule(TOKEN_FOR ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_FUN ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_GETTIME ,literal, NULL, PREC_NONE);
ParseRule(TOKEN_TRUE ,literal, NULL, PREC_NONE);
ParseRule(TOKEN_IF ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_NIL ,literal, NULL, PREC_NONE);
ParseRule(TOKEN_OR ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_PRINT ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_RETURN ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_WHILE ,NULL, NULL, PREC_NONE);
ParseRule(TOKEN_EOF ,NULL, NULL, PREC_NONE);
}