From 14cfc7d0932dd67bfcd980776049e652fee4a5f4 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Fri, 6 Jan 2012 04:51:33 +1000 Subject: Add more LSL parsing structure. --- .gitignore | 2 + LuaSL/src/LuaSL_LSL_tree.c | 278 ++++++++++++++++++++++++++++------ LuaSL/src/LuaSL_LSL_tree.h | 368 +++++++++++++++++++++++++++++++++++++-------- LuaSL/src/LuaSL_lexer.l | 2 +- LuaSL/src/LuaSL_parser.c | 10 +- LuaSL/src/LuaSL_yaccer.y | 12 +- 6 files changed, 558 insertions(+), 114 deletions(-) diff --git a/.gitignore b/.gitignore index 8555fd6..b4f6b51 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ LuaSL/LuaSL_parser LuaSL/src/*.tab.* LuaSL/src/LuaSL_lexer.c LuaSL/src/LuaSL_lexer.h +LuaSL/src/LuaSL_LSL_lexer.c +LuaSL/src/LuaSL_LSL_lexer.h diff --git a/LuaSL/src/LuaSL_LSL_tree.c b/LuaSL/src/LuaSL_LSL_tree.c index 7cebecc..9137692 100644 --- a/LuaSL/src/LuaSL_LSL_tree.c +++ b/LuaSL/src/LuaSL_LSL_tree.c @@ -2,83 +2,275 @@ * Implementation of functions used to build the abstract syntax tree. */ + +#define LSL_Keywords_define +#define LSL_Tokens_define #include "LuaSL_LSL_tree.h" #include + /** - * @brief Allocates space for expression + * @brief Allocates space for an AST leaf * @return The expression or NULL if not enough memory */ -static SExpression* newExpression(EOperationType type, SExpression *left, SExpression *right, int value) + +/* +static LSL_AST *newLeaf(LSL_Type type, LSL_AST *left, LSL_AST *right) { - SExpression* b = malloc(sizeof *b); + LSL_AST *leaf = malloc(sizeof(LSL_AST)); - if (b == NULL) return NULL; + if (leaf == NULL) return NULL; - b->type = type; - b->value = value; - b->left = left; - b->right = right; + leaf->type = type; + leaf->left = left; + leaf->right = right; + leaf->line = -1; + leaf->character = -1; - return b; + return leaf; } +*/ -SExpression* createNumber(int value) +void burnLeaf(LSL_AST *leaf) { - return newExpression(eVALUE, NULL, NULL, value); + if (leaf == NULL) return; + + burnLeaf(leaf->left); + burnLeaf(leaf->right); + free(leaf); } -SExpression *createOperation(EOperationType type, SExpression *left, SExpression *right) +static LSL_Expression *newLSLExpression(LSL_Type type, LSL_Expression *left, LSL_Expression *right) { - return newExpression(type, left, right, 0); + LSL_Expression *exp = malloc(sizeof(LSL_Expression)); + + if (exp == NULL) return NULL; + + exp->type = type; + exp->left = left; + exp->right = right; + exp->expression=0; + + return exp; } -int evaluate(SExpression *e) +void burnLSLExpression(LSL_Expression *exp) { - switch(e->type) - { - case eVALUE: - return e->value; - case eMULTIPLY: - return evaluate(e->left) * evaluate(e->right); - case ePLUS: - return evaluate(e->left) + evaluate(e->right); - default: - // shouldn't be here - return 0; - } + if (exp == NULL) return; + + burnLSLExpression(exp->left); + burnLSLExpression(exp->right); + free(exp); +} + +LSL_Expression *addInteger(int value) +{ + LSL_Expression *exp = newLSLExpression(LSL_INTEGER, NULL, NULL); + + if (exp) + exp->value.integerValue = value; + + return exp; } -void deleteExpression(SExpression *b) +LSL_Expression *addOperation(LSL_Operation type, LSL_Expression *left, LSL_Expression *right) { - if (b == NULL) return; + LSL_Expression *exp = newLSLExpression(LSL_EXPRESSION, left, right); - deleteExpression(b->left); - deleteExpression(b->right); + if (exp) + exp->expression = type; - free(b); + return exp; } -SExpression *getAST(const char *expr) +LSL_Expression *newTree(const char *expr) { - SParserParam p; + LuaSL_yyparseParam param; YY_BUFFER_STATE state; - p.expression = NULL; - if (yylex_init(&(p.scanner))) - return NULL; + param.expression = NULL; + if (yylex_init(&(param.scanner))) + return NULL; + + state = yy_scan_string(expr, param.scanner); + if (yyparse(¶m)) + return NULL; - state = yy_scan_string(expr, p.scanner); - if (yyparse(&p)) - return NULL; + yy_delete_buffer(state, param.scanner); + yylex_destroy(param.scanner); - yy_delete_buffer(state, p.scanner); - yylex_destroy(p.scanner); - return p.expression; + return param.expression; +} + +int evaluateExpression(LSL_Expression *exp, int old) +{ + switch(exp->type) + { + case LSL_COMMENT : + case LSL_TYPE : + case LSL_NAME : + case LSL_IDENTIFIER : + break; + case LSL_FLOAT : return (int) exp->value.floatValue; + case LSL_INTEGER : return exp->value.integerValue; + case LSL_STRING : + case LSL_KEY : + case LSL_VECTOR : + case LSL_ROTATION : + case LSL_LIST : + case LSL_LABEL : + break; + case LSL_EXPRESSION : + { + switch (exp->expression) + { + case LSL_COMMA : + case LSL_INCREMENT_PRE : + case LSL_INCREMENT_POST : + case LSL_DECREMENT_PRE : + case LSL_DECREMENT_POST : + case LSL_DOT : + case LSL_ASSIGNMENT_PLAIN : + case LSL_ASSIGNMENT_DIVIDE : + case LSL_ASSIGNMENT_MODULO : + case LSL_ASSIGNMENT_MULTIPLY : + case LSL_ASSIGNMENT_SUBTRACT : + case LSL_ASSIGNMENT_ADD : + case LSL_ASSIGNMENT_CONCATENATE : + case LSL_PARENTHESIS_OPEN : + case LSL_PARENTHESIS_CLOSE : + case LSL_BRACKET_OPEN : + case LSL_BRACKET_CLOSE : + case LSL_ANGLE_OPEN : + case LSL_ANGLE_CLOSE : + case LSL_TYPECAST : + case LSL_BIT_NOT : + case LSL_BOOL_NOT : + case LSL_NEGATION : + break; + case LSL_DIVIDE : return evaluateExpression(exp->left, old) / evaluateExpression(exp->right, old); + case LSL_MODULO : return evaluateExpression(exp->left, old) % evaluateExpression(exp->right, old); + case LSL_MULTIPLY : return evaluateExpression(exp->left, old) * evaluateExpression(exp->right, old); + case LSL_DOT_PRODUCT : break; + case LSL_CROSS_PRODUCT : break; + case LSL_SUBTRACT : return evaluateExpression(exp->left, old) - evaluateExpression(exp->right, old); + case LSL_ADD : return evaluateExpression(exp->left, old) + evaluateExpression(exp->right, old); + case LSL_CONCATENATE : break; + case LSL_LEFT_SHIFT : return evaluateExpression(exp->left, old) << evaluateExpression(exp->right, old); + case LSL_RIGHT_SHIFT : return evaluateExpression(exp->left, old) >> evaluateExpression(exp->right, old); + case LSL_LESS_THAN : return evaluateExpression(exp->left, old) < evaluateExpression(exp->right, old); + case LSL_GREATER_THAN : return evaluateExpression(exp->left, old) > evaluateExpression(exp->right, old); + case LSL_LESS_EQUAL : return evaluateExpression(exp->left, old) <= evaluateExpression(exp->right, old); + case LSL_GREATER_EQUAL : return evaluateExpression(exp->left, old) >= evaluateExpression(exp->right, old); + case LSL_EQUAL : return evaluateExpression(exp->left, old) == evaluateExpression(exp->right, old); + case LSL_NOT_EQUAL : return evaluateExpression(exp->left, old) != evaluateExpression(exp->right, old); + case LSL_BIT_AND : return evaluateExpression(exp->left, old) & evaluateExpression(exp->right, old); + case LSL_BIT_XOR : return evaluateExpression(exp->left, old) ^ evaluateExpression(exp->right, old); + case LSL_BIT_OR : return evaluateExpression(exp->left, old) | evaluateExpression(exp->right, old); + case LSL_BOOL_OR : return evaluateExpression(exp->left, old) || evaluateExpression(exp->right, old); + case LSL_BOOL_AND : return evaluateExpression(exp->left, old) && evaluateExpression(exp->right, old); + } + break; + } + case LSL_DO : + case LSL_FOR : + case LSL_IF : + case LSL_ELSE : + case LSL_ELSEIF : + case LSL_JUMP : + case LSL_STATE_CHANGE : + case LSL_WHILE : + case LSL_RETURN : + case LSL_STATEMENT : + case LSL_BLOCK : + case LSL_PARAMETER : + case LSL_FUNCTION : + case LSL_STATE : + case LSL_SCRIPT : + break; + } + + return old; + +} + +void outputExpression(LSL_Expression *exp) +{ + switch(exp->type) + { + case LSL_COMMENT : return; + case LSL_TYPE : return; + case LSL_NAME : return; + case LSL_IDENTIFIER : return; + case LSL_FLOAT : printf("%f", exp->value.floatValue); break; + case LSL_INTEGER : printf("%d", exp->value.integerValue); break; + case LSL_STRING : return; + case LSL_KEY : return; + case LSL_VECTOR : return; + case LSL_ROTATION : return; + case LSL_LIST : return; + case LSL_LABEL : return; + case LSL_EXPRESSION : + outputExpression(exp->left); + printf(" %s ", LSL_Tokens[exp->expression].token); + outputExpression(exp->right); + break; + case LSL_DO : return; + case LSL_FOR : return; + case LSL_IF : return; + case LSL_ELSE : return; + case LSL_ELSEIF : return; + case LSL_JUMP : return; + case LSL_STATE_CHANGE : return; + case LSL_WHILE : return; + case LSL_RETURN : return; + case LSL_STATEMENT : return; + case LSL_BLOCK : return; + case LSL_PARAMETER : return; + case LSL_FUNCTION : return; + case LSL_STATE : return; + case LSL_SCRIPT : return; + } +} + +void convertExpression2Lua(LSL_Expression *exp) +{ + switch(exp->type) + { + case LSL_COMMENT : return; + case LSL_TYPE : return; + case LSL_NAME : return; + case LSL_IDENTIFIER : return; + case LSL_FLOAT : return; + case LSL_INTEGER : return; + case LSL_STRING : return; + case LSL_KEY : return; + case LSL_VECTOR : return; + case LSL_ROTATION : return; + case LSL_LIST : return; + case LSL_LABEL : return; + case LSL_EXPRESSION : return; + case LSL_DO : return; + case LSL_FOR : return; + case LSL_IF : return; + case LSL_ELSE : return; + case LSL_ELSEIF : return; + case LSL_JUMP : return; + case LSL_STATE_CHANGE : return; + case LSL_WHILE : return; + case LSL_RETURN : return; + case LSL_STATEMENT : return; + case LSL_BLOCK : return; + case LSL_PARAMETER : return; + case LSL_FUNCTION : return; + case LSL_STATE : return; + case LSL_SCRIPT : return; + } } int yyerror(const char *msg) { - fprintf(stderr,"Error:%s\n",msg); return 0; + fprintf(stderr, "Parser error: %s\n", msg); + return 0; } diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h index 9c27a8f..a5d090e 100644 --- a/LuaSL/src/LuaSL_LSL_tree.h +++ b/LuaSL/src/LuaSL_LSL_tree.h @@ -8,39 +8,306 @@ #define YY_NO_UNISTD_H 1 #endif // YY_NO_UNISTD_H +// http://w-hat.com/stackdepth is a useful discussion about some aspects of the LL parser. -/** - * @brief The operation type - */ -typedef enum tagEOperationType +typedef enum { - eVALUE, - eMULTIPLY, - ePLUS -} EOperationType; + LSL_LEFT2RIGHT = 0, + LSL_RIGHT2LEFT = 1, + LSL_INNER2OUTER = 2, + LSL_UNARY = 4, + LSL_ASSIGNMENT = 8, + LSL_CREATION = 16 +} LSL_Flags; -/** - * @brief The expression structure - */ -typedef struct tagSExpression +typedef enum // In order of precedence, high to low. + // Left to right, unless oterwise stated. + // According to http://wiki.secondlife.com/wiki/Category:LSL_Operators +{ + LSL_COMMA, + LSL_INCREMENT_PRE, // Right to left. + LSL_INCREMENT_POST, // Right to left. + LSL_DECREMENT_PRE, // Right to left. + LSL_DECREMENT_POST, // Right to left. + LSL_DOT, // Right to left. + LSL_ASSIGNMENT_PLAIN, // Right to left. + LSL_ASSIGNMENT_DIVIDE, // Right to left. + LSL_ASSIGNMENT_MODULO, // Right to left. + LSL_ASSIGNMENT_MULTIPLY, // Right to left. + LSL_ASSIGNMENT_SUBTRACT, // Right to left. + LSL_ASSIGNMENT_ADD, // Right to left. + LSL_ASSIGNMENT_CONCATENATE, // Right to left. + LSL_PARENTHESIS_OPEN, // Inner to outer. + LSL_PARENTHESIS_CLOSE, // Inner to outer. + LSL_BRACKET_OPEN, // Inner to outer. + LSL_BRACKET_CLOSE, // Inner to outer. + LSL_ANGLE_OPEN, + LSL_ANGLE_CLOSE, + LSL_TYPECAST, // Right to left. + LSL_BIT_NOT, // Right to left. + LSL_BOOL_NOT, // Right to left. + LSL_NEGATION, // Right to left. + LSL_DIVIDE, + LSL_MODULO, + LSL_MULTIPLY, + LSL_DOT_PRODUCT, + LSL_CROSS_PRODUCT, + LSL_SUBTRACT, + LSL_ADD, + LSL_CONCATENATE, + LSL_LEFT_SHIFT, + LSL_RIGHT_SHIFT, + LSL_LESS_THAN, + LSL_GREATER_THAN, + LSL_LESS_EQUAL, + LSL_GREATER_EQUAL, + LSL_EQUAL, + LSL_NOT_EQUAL, + LSL_BIT_AND, + LSL_BIT_XOR, + LSL_BIT_OR, + LSL_BOOL_OR, + LSL_BOOL_AND +} LSL_Operation; + +typedef struct +{ +// LSL_Operation operation, + char *token; + LSL_Flags flags; +} LSL_Operator; + +// QUIRK - Seems to be some disagreement about BOOL_AND/BOOL_OR precedence. Either they are equal, or OR is higher. +// QUIRK - Conditionals are executed right to left. Or left to right, depending on who you ask. lol +// QUIRK - No boolean short circuiting. + +#ifdef LSL_Tokens_define +LSL_Operator LSL_Tokens[] = { - EOperationType type;///< type of operation + {",", LSL_LEFT2RIGHT}, + {"++", LSL_RIGHT2LEFT | LSL_UNARY}, + {"++", LSL_RIGHT2LEFT | LSL_UNARY}, + {"--", LSL_RIGHT2LEFT | LSL_UNARY}, + {"--", LSL_RIGHT2LEFT | LSL_UNARY}, + {".", LSL_RIGHT2LEFT}, + {"=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, + {"/=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, + {"%=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, + {"*=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, + {"-=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, + {"+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, + {"+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT}, + {"(", LSL_INNER2OUTER}, + {")", LSL_INNER2OUTER}, + {"[", LSL_INNER2OUTER | LSL_CREATION}, + {"]", LSL_INNER2OUTER | LSL_CREATION}, + {"<", LSL_LEFT2RIGHT | LSL_CREATION}, + {">", LSL_LEFT2RIGHT | LSL_CREATION}, + {"()", LSL_RIGHT2LEFT | LSL_UNARY}, + {"~", LSL_RIGHT2LEFT | LSL_UNARY}, + {"!", LSL_RIGHT2LEFT | LSL_UNARY}, + {"-", LSL_RIGHT2LEFT | LSL_UNARY}, + {"/", LSL_LEFT2RIGHT}, + {"%", LSL_LEFT2RIGHT}, + {"*", LSL_LEFT2RIGHT}, + {"*", LSL_LEFT2RIGHT}, + {"%", LSL_LEFT2RIGHT}, + {"-", LSL_LEFT2RIGHT}, + {"+", LSL_LEFT2RIGHT}, + {"+", LSL_LEFT2RIGHT}, + {"<<", LSL_LEFT2RIGHT}, + {">>", LSL_LEFT2RIGHT}, + {"<", LSL_LEFT2RIGHT}, + {">", LSL_LEFT2RIGHT}, + {"<=", LSL_LEFT2RIGHT}, + {">=", LSL_LEFT2RIGHT}, + {"==", LSL_LEFT2RIGHT}, + {"!=", LSL_LEFT2RIGHT}, + {"&", LSL_LEFT2RIGHT}, + {"^", LSL_LEFT2RIGHT}, + {"|", LSL_LEFT2RIGHT}, + {"||", LSL_LEFT2RIGHT}, + {"&&", LSL_LEFT2RIGHT} +}; +#endif + +typedef enum +{ + LSL_COMMENT, + LSL_TYPE, + LSL_NAME, + LSL_IDENTIFIER, + LSL_FLOAT, + LSL_INTEGER, + LSL_STRING, + LSL_KEY, + LSL_VECTOR, + LSL_ROTATION, + LSL_LIST, + LSL_LABEL, + LSL_EXPRESSION, + LSL_DO, + LSL_FOR, + LSL_IF, + LSL_ELSE, + LSL_ELSEIF, + LSL_JUMP, + LSL_STATE_CHANGE, + LSL_WHILE, + LSL_RETURN, + LSL_STATEMENT, + LSL_BLOCK, + LSL_PARAMETER, + LSL_FUNCTION, + LSL_STATE, + LSL_SCRIPT +} LSL_Type; + +#ifdef LSL_Keywords_define +char *LSL_Keywords[] = +{ + "//", // Also "/*", + "", + "", + "", + "float", + "integer", + "string", + "key", + "vector", + "rotation", + "list", + "@", + "", + "do", + "for", + "if", + "else", + "else if", + "jump", + "state", + "while", + "return", + ";", + "{}", + "", + "", + "", + "" +}; +#endif + +typedef union +{ + float floatValue; + int integerValue; + char *stringValue; + char *keyValue; + float vectorValue[3]; + float rotationValue[4]; + union LSL_Leaf *listValue; +} LSL_Value; + +typedef struct +{ + char *name; + LSL_Type type; + LSL_Value value; +} LSL_Identifier; + +typedef struct LSL_Expression +{ + struct LSL_Expression *left; + struct LSL_Expression *right; + LSL_Value value; + LSL_Operation expression; + LSL_Type type; +} LSL_Expression; + +typedef struct +{ + LSL_Type type; + LSL_Expression *expressions; +} LSL_Statement; + +typedef struct +{ + LSL_Statement *statements; +} LSL_Block; + +typedef struct +{ + char *name; + LSL_Identifier *parameters; + LSL_Block block; + LSL_Type type; +} LSL_Function; + +typedef struct +{ + char *name; + LSL_Function *handlers; +} LSL_State; + +typedef struct +{ + char *name; + LSL_Identifier *variables; + LSL_Function *functions; + LSL_State *states; +} LSL_Script; + +typedef union LSL_Leaf +{ + char *commentValue; + LSL_Type typeValue; + char *nameValue; + LSL_Identifier *identifierValue; + float floatValue; + int integerValue; + char *stringValue; + char *keyValue; + float vectorValue[3]; + float rotationValue[4]; + union LSL_Leaf *listValue; + char *labelValue; +// LSL_Operation expressionValue; + LSL_Expression *expressionValue; + LSL_Statement *doValue; + LSL_Statement *forValue; + LSL_Statement *ifValue; + LSL_Statement *elseValue; + LSL_Statement *elseIfValue; + char *jumpValue; + char *stateChangeValue; + LSL_Statement *statementValue; + LSL_Identifier *parameterValue; + LSL_Function *functionValue; + LSL_State *stateValue; + LSL_Script *scriptValue; +} LSL_Leaf; + +typedef struct LSL_AST +{ + struct LSL_AST *left; + struct LSL_AST *right; + int line; + int character; + LSL_Type type; + LSL_Leaf content; +} LSL_AST; - int value;///< valid only when type is eVALUE - struct tagSExpression* left; ///< left side of the tree - struct tagSExpression* right;///< right side of the tree -} SExpression; /** * @brief The structure used by flex and bison */ -typedef union tagTypeParser -{ - SExpression *expression; - int value; - int ival; - float fval; - char *sval; +//typedef union tagTypeParser +//{ +// SExpression *expression; +// int value; +// int ival; +// float fval; +// char *sval; // class LLScriptType *type; // class LLScriptConstant *constant; // class LLScriptIdentifier *identifier; @@ -55,10 +322,10 @@ typedef union tagTypeParser // class LLScriptState *state; // class LLScritpGlobalStorage *global_store; // class LLScriptScript *script; -}STypeParser; +//}STypeParser; // define the type for flex and bison -#define YYSTYPE STypeParser +#define YYSTYPE LSL_Leaf #ifndef excludeLexer @@ -66,47 +333,28 @@ typedef union tagTypeParser #endif -/** - * @brief structure given as argument to the reentrant 'yyparse' function. - */ -typedef struct tagSParserParam +typedef struct { yyscan_t scanner; - SExpression *expression; -}SParserParam; - + LSL_Expression *expression; +} LuaSL_yyparseParam; + + +void burnLeaf(LSL_AST *leaf); +void burnLSLExpression(LSL_Expression *exp); +LSL_Expression *addInteger(int value); +LSL_Expression *addOperation(LSL_Operation type, LSL_Expression *left, LSL_Expression *right); +LSL_Expression *newTree(const char *expr); +int evaluateExpression(LSL_Expression *exp, int old); +void outputExpression(LSL_Expression *exp); +void convertExpression2Lua(LSL_Expression *exp); + // the parameter name (of the reentrant 'yyparse' function) // data is a pointer to a 'SParserParam' structure #define YYPARSE_PARAM data // the argument for the 'yylex' function -#define YYLEX_PARAM ((SParserParam*)data)->scanner - -/** - * @brief It creates an identifier - * @param value The number value - * @return The expression or NULL in case of no memory - */ -SExpression* createNumber(int value); - -/** - * @brief It creates an operation - * @param type The operation type - * @param left The left operand - * @param right The right operand - * @return The expression or NULL in case of no memory - */ -SExpression* createOperation(EOperationType type, SExpression *left, SExpression *right); - -/** - * @brief Deletes a expression - * @param b The expression - */ -void deleteExpression(SExpression *b); - -SExpression *getAST(const char *expr); - -int evaluate(SExpression *e); +#define YYLEX_PARAM ((LuaSL_yyparseParam*)data)->scanner int yyerror(const char *msg); int yyparse(void *param); diff --git a/LuaSL/src/LuaSL_lexer.l b/LuaSL/src/LuaSL_lexer.l index 93dd39c..d204916 100644 --- a/LuaSL/src/LuaSL_lexer.l +++ b/LuaSL/src/LuaSL_lexer.l @@ -19,7 +19,7 @@ WS [ \r\n\t]* %% {WS} { /* Skip blanks. */ } -{NUMBER} { sscanf(yytext,"%d",&yylval->value); return TOKEN_NUMBER; } +{NUMBER} { sscanf(yytext,"%d",&yylval->integerValue); return TOKEN_NUMBER; } {MULTIPLY} { return TOKEN_MULTIPLY; } {PLUS} { return TOKEN_PLUS; } diff --git a/LuaSL/src/LuaSL_parser.c b/LuaSL/src/LuaSL_parser.c index f5a56d3..35cb782 100644 --- a/LuaSL/src/LuaSL_parser.c +++ b/LuaSL/src/LuaSL_parser.c @@ -5,14 +5,16 @@ int main(void) { const char test[] = " 4 + 2*10 + 3*( 5 + 1 )"; - SExpression *e = NULL; + LSL_Expression *exp; - if ((e = getAST(test))) + if ((exp = newTree(test))) { - int result = evaluate(e); + int result = evaluateExpression(exp, 0); printf("Result of '%s' is %d\n", test, result); - deleteExpression(e); + outputExpression(exp); + printf("\n"); + burnLSLExpression(exp); } return 0; diff --git a/LuaSL/src/LuaSL_yaccer.y b/LuaSL/src/LuaSL_yaccer.y index 19009bf..820f7da 100644 --- a/LuaSL/src/LuaSL_yaccer.y +++ b/LuaSL/src/LuaSL_yaccer.y @@ -14,21 +14,21 @@ %token TOKEN_PLUS %token TOKEN_MULTIPLY -%token TOKEN_NUMBER +%token TOKEN_NUMBER -%type expr +%type expr %% input: - expr { ((SParserParam*)data)->expression = $1; } + expr { ((LuaSL_yyparseParam*)data)->expression = $1; } ; expr: - expr TOKEN_PLUS expr { $$ = createOperation( ePLUS, $1, $3 ); } - | expr TOKEN_MULTIPLY expr { $$ = createOperation( eMULTIPLY, $1, $3 ); } + expr TOKEN_PLUS expr { $$ = addOperation( LSL_ADD, $1, $3 ); } + | expr TOKEN_MULTIPLY expr { $$ = addOperation( LSL_MULTIPLY, $1, $3 ); } | TOKEN_LPAREN expr TOKEN_RPAREN { $$ = $2; } - | TOKEN_NUMBER { $$ = createNumber($1); } + | TOKEN_NUMBER { $$ = addInteger($1); } ; %% -- cgit v1.1