2 * Acess2 - SpiderScript
8 #include <spiderscript.h>
13 tAST_Script *Parse_Buffer(tSpiderVariant *Variant, char *Buffer);
14 tAST_Node *Parse_DoCodeBlock(tParser *Parser);
15 tAST_Node *Parse_DoExpr(tParser *Parser);
17 tAST_Node *Parse_DoExpr0(tParser *Parser); // Assignment
18 tAST_Node *Parse_DoExpr1(tParser *Parser); // Boolean Operators
19 tAST_Node *Parse_DoExpr2(tParser *Parser); // Comparison Operators
20 tAST_Node *Parse_DoExpr3(tParser *Parser); // Bitwise Operators
21 tAST_Node *Parse_DoExpr4(tParser *Parser); // Bit Shifts
22 tAST_Node *Parse_DoExpr5(tParser *Parser); // Arithmatic
23 tAST_Node *Parse_DoExpr6(tParser *Parser); // Mult & Div
25 tAST_Node *Parse_DoParen(tParser *Parser); // Parenthesis (Always Last)
26 tAST_Node *Parse_DoValue(tParser *Parser); // Values
28 tAST_Node *Parse_GetString(tParser *Parser);
29 tAST_Node *Parse_GetNumeric(tParser *Parser);
30 tAST_Node *Parse_GetVariable(tParser *Parser);
31 tAST_Node *Parse_GetIdent(tParser *Parser);
33 void SyntaxAssert(int Have, int Want);
37 * \brief Parse a buffer into a syntax tree
39 tAST_Script *Parse_Buffer(tSpiderVariant *Variant, char *Buffer)
42 tParser *Parser = &parser; //< Keeps code consitent
49 parser.BufStart = Buffer;
50 parser.CurPos = Buffer;
52 ret = AST_NewScript();
53 mainCode = AST_NewCodeBlock();
57 switch( GetToken(Parser) )
59 case TOK_RWD_FUNCTION:
61 SyntaxAssert( GetToken(Parser), TOK_IDENT );
62 name = strndup( Parser->TokenStr, Parser->TokenLen );
63 fcn = AST_AppendFunction( ret, name );
66 SyntaxAssert( GetToken(Parser), TOK_PAREN_OPEN );
68 SyntaxAssert( GetToken(Parser), TOK_PAREN_CLOSE );
70 AST_SetFunctionCode( fcn, Parse_DoCodeBlock(Parser) );
75 AST_AppendNode( mainCode, Parse_DoExpr(Parser) );
80 fcn = AST_AppendFunction( ret, "" );
81 AST_SetFunctionCode( fcn, mainCode );
87 * \brief Parse a block of code surrounded by { }
89 tAST_Node *Parse_DoCodeBlock(tParser *Parser)
92 SyntaxAssert( GetToken(Parser), TOK_BRACE_OPEN );
94 ret = AST_NewCodeBlock();
96 while( GetToken(Parser) != TOK_BRACE_CLOSE )
98 AST_AppendNode( ret, Parse_DoExpr(Parser) );
99 SyntaxAssert( GetToken(Parser), TOK_SEMICOLON );
105 * \brief Parse an expression
107 tAST_Node *Parse_DoExpr(tParser *Parser)
109 return Parse_DoExpr0(Parser);
113 * \brief Assignment Operations
115 tAST_Node *Parse_DoExpr0(tParser *Parser)
117 tAST_Node *ret = Parse_DoExpr1(Parser);
120 switch(LookAhead(Parser))
123 GetToken(Parser); // Eat Token
124 ret = AST_NewAssign(NODETYPE_NOP, ret, Parse_DoExpr0(Parser));
128 GetToken(Parser); // Eat Token
129 ret = AST_NewAssignOp(ret, NODETYPE_DIVIDE, DoExpr0(Parser));
132 GetToken(Parser); // Eat Token
133 ret = AST_NewAssignOp(ret, NODETYPE_MULTIPLY, DoExpr0(Parser));
142 * \brief Logical/Boolean Operators
144 tAST_Node *Parse_DoExpr1(tParser *Parser)
146 tAST_Node *ret = Parse_DoExpr2(Parser);
148 switch(GetToken(Parser))
151 ret = AST_NewBinOp(NODETYPE_LOGICALAND, ret, Parse_DoExpr1(Parser));
154 ret = AST_NewBinOp(NODETYPE_LOGICALOR, ret, Parse_DoExpr1(Parser));
157 ret = AST_NewBinOp(NODETYPE_LOGICALXOR, ret, Parse_DoExpr1(Parser));
166 // --------------------
167 // Expression 2 - Comparison Operators
168 // --------------------
169 tAST_Node *Parse_DoExpr2(tParser *Parser)
171 tAST_Node *ret = Parse_DoExpr3(Parser);
174 switch(GetToken(Parser))
177 ret = AST_NewBinOp(NODETYPE_EQUALS, ret, Parse_DoExpr2(Parser));
180 ret = AST_NewBinOp(NODETYPE_LESSTHAN, ret, Parse_DoExpr2(Parser));
183 ret = AST_NewBinOp(NODETYPE_GREATERTHAN, ret, Parse_DoExpr2(Parser));
193 * \brief Bitwise Operations
195 tAST_Node *Parse_DoExpr3(tParser *Parser)
197 tAST_Node *ret = Parse_DoExpr4(Parser);
200 switch(GetToken(Parser))
203 ret = AST_NewBinOp(NODETYPE_BWOR, ret, Parse_DoExpr3(Parser));
206 ret = AST_NewBinOp(NODETYPE_BWAND, ret, Parse_DoExpr3(Parser));
209 ret = AST_NewBinOp(NODETYPE_BWXOR, ret, Parse_DoExpr3(Parser));
218 // --------------------
219 // Expression 4 - Shifts
220 // --------------------
221 tAST_Node *Parse_DoExpr4(tParser *Parser)
223 tAST_Node *ret = Parse_DoExpr5(Parser);
225 switch(GetToken(Parser))
228 ret = AST_NewBinOp(NODETYPE_BITSHIFTLEFT, ret, Parse_DoExpr5(Parser));
231 ret = AST_NewBinOp(NODETYPE_BITSHIFTRIGHT, ret, Parse_DoExpr5(Parser));
241 // --------------------
242 // Expression 5 - Arithmatic
243 // --------------------
244 tAST_Node *Parse_DoExpr5(tParser *Parser)
246 tAST_Node *ret = Parse_DoExpr6(Parser);
248 switch(GetToken(Parser))
251 ret = AST_NewBinOp(NODETYPE_ADD, ret, Parse_DoExpr5(Parser));
254 ret = AST_NewBinOp(NODETYPE_SUBTRACT, ret, Parse_DoExpr5(Parser));
264 // --------------------
265 // Expression 6 - Multiplcation & Division
266 // --------------------
267 tAST_Node *Parse_DoExpr6(tParser *Parser)
269 tAST_Node *ret = Parse_DoParen(Parser);
271 switch(GetToken(Parser))
274 ret = AST_NewBinOp(NODETYPE_MULTIPLY, ret, Parse_DoExpr6(Parser));
277 ret = AST_NewBinOp(NODETYPE_DIVIDE, ret, Parse_DoExpr6(Parser));
288 // --------------------
289 // 2nd Last Expression - Parens
290 // --------------------
291 tAST_Node *Parse_DoParen(tParser *Parser)
293 if(LookAhead(Parser) == TOK_PAREN_OPEN)
297 ret = Parse_DoExpr0(Parser);
298 SyntaxAssert(GetToken(Parser), TOK_PAREN_CLOSE);
302 return Parse_DoValue(Parser);
305 // --------------------
306 // Last Expression - Value
307 // --------------------
308 tAST_Node *Parse_DoValue(tParser *Parser)
310 int tok = LookAhead(Parser);
314 case TOK_STR: return Parse_GetString(Parser);
315 case TOK_INTEGER: return Parse_GetNumeric(Parser);
316 case TOK_IDENT: return Parse_GetIdent(Parser);
317 case TOK_VARIABLE: return Parse_GetVariable(Parser);
320 //ParseError2( tok, TOK_T_VALUE );
326 * \brief Get a string
328 tAST_Node *Parse_GetString(tParser *Parser)
332 // TODO: Parse Escape Codes
333 ret = AST_NewString( Parser->TokenStr+1, Parser->TokenLen-2 );
338 * \brief Get a numeric value
340 tAST_Node *Parse_GetNumeric(tParser *Parser)
344 value = atoi( Parser->TokenStr );
345 return AST_NewInteger( value );
349 * \brief Get a variable
351 tAST_Node *Parse_GetVariable(tParser *Parser)
355 SyntaxAssert( GetToken(Parser), TOK_VARIABLE );
356 name = strndup( Parser->TokenStr+1, Parser->TokenLen-1 );
357 ret = AST_NewVariable( name );
363 * \brief Get an identifier (constand or function call)
365 tAST_Node *Parse_GetIdent(tParser *Parser)
369 SyntaxAssert( GetToken(Parser), TOK_IDENT );
370 name = strndup( Parser->TokenStr, Parser->TokenLen );
372 if( GetToken(Parser) == TOK_PAREN_OPEN )
375 ret = AST_NewFunctionCall( name );
377 if( GetToken(Parser) != TOK_PAREN_CLOSE )
381 AST_AppendFunctionCallArg( ret, Parse_DoExpr0(Parser) );
382 } while(GetToken(Parser) == TOK_COMMA);
383 SyntaxAssert( Parser->Token, TOK_PAREN_CLOSE );
389 ret = AST_NewConstant( name );
397 * \brief Check for an error
399 void SyntaxAssert(int Have, int Want)
402 fprintf(stderr, "ERROR: Expected %i, got %i\n", Want, Have);
403 //longjmp(jmpTarget, 1);