2 * Acess2 - SpiderScript
9 #include <spiderscript.h>
10 #define WANT_TOKEN_STRINGS 1
15 #define SUPPORT_BREAK_TAGS 1
18 tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const char *Filename);
19 void *Parse_FunctionDefinition(tAST_Script *Script, tSpiderVariant *Variant, tParser *Parser, int Type);
20 tAST_Node *Parse_DoCodeBlock(tParser *Parser);
21 tAST_Node *Parse_DoBlockLine(tParser *Parser);
22 tAST_Node *Parse_GetVarDef(tParser *Parser, int Type);
24 tAST_Node *Parse_DoExpr0(tParser *Parser); // Assignment
25 tAST_Node *Parse_DoExpr1(tParser *Parser); // Boolean Operators
26 tAST_Node *Parse_DoExpr2(tParser *Parser); // Comparison Operators
27 tAST_Node *Parse_DoExpr3(tParser *Parser); // Bitwise Operators
28 tAST_Node *Parse_DoExpr4(tParser *Parser); // Bit Shifts
29 tAST_Node *Parse_DoExpr5(tParser *Parser); // Arithmatic
30 tAST_Node *Parse_DoExpr6(tParser *Parser); // Mult & Div
31 tAST_Node *Parse_DoExpr7(tParser *Parser); // Right Unary Operations
32 tAST_Node *Parse_DoExpr8(tParser *Parser); // Left Unary Operations
34 tAST_Node *Parse_DoParen(tParser *Parser); // Parenthesis (Always Last)
35 tAST_Node *Parse_DoValue(tParser *Parser); // Values
37 tAST_Node *Parse_GetString(tParser *Parser);
38 tAST_Node *Parse_GetNumeric(tParser *Parser);
39 tAST_Node *Parse_GetVariable(tParser *Parser);
40 tAST_Node *Parse_GetIdent(tParser *Parser, int bObjectCreate);
42 void SyntaxAssert(tParser *Parser, int Have, int Want);
43 void SyntaxError(tParser *Parser, int bFatal, const char *Message, ...);
45 #define SyntaxAssert(_parser, _have, _want) do { \
46 int have = (_have), want = (_want); \
47 if( (have) != (want) ) { \
48 SyntaxError(Parser, 1, "Unexpected %s(%i), expecting %s(%i)\n", \
49 csaTOKEN_NAMES[have], have, csaTOKEN_NAMES[want], want); \
54 #define TODO(Parser, message...) do {\
55 fprintf(stderr, "TODO: "message);\
56 longjmp(Parser->JmpTarget, -1);\
61 * \brief Parse a buffer into a syntax tree
63 tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const char *Filename)
66 tParser *Parser = &parser; //< Keeps code consistent
68 tAST_Node *mainCode, *node;
73 printf("Parse_Buffer: (Variant=%p, Buffer=%p)\n", Variant, Buffer);
77 parser.LastToken = -1;
78 parser.NextToken = -1;
80 parser.BufStart = Buffer;
81 parser.CurPos = Buffer;
82 // hackery to do reference counting
83 parser.Filename = malloc(sizeof(int)+strlen(Filename)+1);
84 strcpy(parser.Filename + sizeof(int), Filename);
85 *(int*)(parser.Filename) = 0; // Set reference count
86 parser.Filename += sizeof(int); // Move filename
89 ret = AST_NewScript();
90 mainCode = AST_NewCodeBlock(&parser);
92 // Give us an error fallback
93 if( setjmp( parser.JmpTarget ) != 0 )
95 AST_FreeNode( mainCode );
97 for(fcn = ret->Functions; fcn; )
100 tAST_Function *nextFcn;
101 AST_FreeNode( fcn->Code );
102 for(var = fcn->Arguments; var;)
104 tAST_Node *nextVar = var->NextSibling;
118 while(Parser->Token != TOK_EOF)
120 switch( GetToken(Parser) )
125 // Typed variables/functions
126 case TOKEN_GROUP_TYPES:
127 TOKEN_GET_DATATYPE(type, Parser->Token);
129 switch(GetToken(Parser))
131 // Define a function (pass on to the other function definition code)
134 if( Parse_FunctionDefinition(ret, Variant, Parser, type) == NULL )
135 longjmp(Parser->JmpTarget, -1);
139 node = Parse_GetVarDef(Parser, type);
140 if(!node) longjmp(Parser->JmpTarget, -1);
142 AST_AppendNode( mainCode, node );
143 // Can't use SyntaxAssert because that returns
144 if(GetToken(Parser) != TOK_SEMICOLON) {
145 SyntaxError(Parser, 1, "Unexpected %s, expected TOK_SEMICOLON",
146 csaTOKEN_NAMES[Parser->Token]);
147 longjmp(Parser->JmpTarget, -1);
151 SyntaxError(Parser, 1, "Unexpected %s, expected TOK_IDENT or TOK_VARIABLE\n",
152 csaTOKEN_NAMES[Parser->Token]);
158 case TOK_RWD_FUNCTION:
159 if( !Variant->bDyamicTyped ) {
160 SyntaxError(Parser, 1, "Dynamic functions are invalid in static mode");
161 longjmp(Parser->JmpTarget, -1);
164 type = SS_DATATYPE_DYNAMIC;
166 if( Parse_FunctionDefinition(ret, Variant, Parser, SS_DATATYPE_DYNAMIC) == NULL )
167 longjmp(Parser->JmpTarget, -1);
171 // Ordinary Statement
174 node = Parse_DoBlockLine(Parser);
175 if(!node) longjmp(Parser->JmpTarget, -1);
176 AST_AppendNode( mainCode, node );
180 // Jump to error handler on error
182 longjmp(Parser->JmpTarget, -1);
185 fcn = AST_AppendFunction( ret, "", SS_DATATYPE_INTEGER );
186 AST_SetFunctionCode( fcn, mainCode );
188 //printf("---- %p parsed as SpiderScript ----\n", Buffer);
193 void *Parse_FunctionDefinition(tAST_Script *Script, tSpiderVariant *Variant, tParser *Parser, int Type)
199 SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
201 name = strndup( Parser->TokenStr, Parser->TokenLen );
202 fcn = AST_AppendFunction( Script, name, Type );
204 printf("DefFCN %s\n", name);
209 SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN );
210 if( LookAhead(Parser) != TOK_PAREN_CLOSE )
213 type = SS_DATATYPE_DYNAMIC;
215 // Non dynamic typed variants must use data types
216 if( !Variant->bDyamicTyped ) {
217 TOKEN_GET_DATATYPE(type, Parser->Token);
220 AST_AppendFunctionArg(fcn, Parse_GetVarDef(Parser, type));
221 } while(GetToken(Parser) == TOK_COMMA);
225 SyntaxAssert(Parser, Parser->Token, TOK_PAREN_CLOSE );
227 AST_SetFunctionCode( fcn, Parse_DoCodeBlock(Parser) );
233 * \brief Parse a block of code surrounded by { }
235 tAST_Node *Parse_DoCodeBlock(tParser *Parser)
239 // Check if we are being called for a one-liner
240 if( GetToken(Parser) != TOK_BRACE_OPEN ) {
242 return Parse_DoBlockLine(Parser);
245 ret = AST_NewCodeBlock(Parser);
247 while( LookAhead(Parser) != TOK_BRACE_CLOSE )
249 tAST_Node *node = Parse_DoBlockLine(Parser);
254 AST_AppendNode( ret, node );
256 GetToken(Parser); // Omnomnom
261 * \brief Parse a line in a block
263 tAST_Node *Parse_DoBlockLine(tParser *Parser)
267 //printf("Parse_DoBlockLine: Line %i\n", Parser->CurLine);
269 switch(LookAhead(Parser))
273 return Parse_DoCodeBlock(Parser);
280 // Return from a method
283 ret = AST_NewUniOp(Parser, NODETYPE_RETURN, Parse_DoExpr0(Parser));
286 // Break / Continue (end a loop / go to next iteration)
287 case TOK_RWD_CONTINUE:
292 tok = GetToken(Parser);
293 // Get the number of nesting levels to break
294 if(LookAhead(Parser) == TOK_IDENT)
297 ident = strndup(Parser->TokenStr, Parser->TokenLen);
302 case TOK_RWD_BREAK: ret = AST_NewBreakout(Parser, NODETYPE_BREAK, ident); break;
303 case TOK_RWD_CONTINUE: ret = AST_NewBreakout(Parser, NODETYPE_CONTINUE, ident); break;
305 SyntaxError(Parser, 1, "BUG Unhandled break/continue (%s)",
306 csaTOKEN_NAMES[tok]);
309 if(ident) free(ident);
313 // Control Statements
316 tAST_Node *cond, *true, *false = NULL;
317 GetToken(Parser); // eat the if
319 SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN);
320 cond = Parse_DoExpr0(Parser); // Get condition
321 SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
322 true = Parse_DoCodeBlock(Parser);
323 if( LookAhead(Parser) == TOK_RWD_ELSE ) {
325 false = Parse_DoCodeBlock(Parser);
328 false = AST_NewNop(Parser);
329 ret = AST_NewIf(Parser, cond, true, false);
336 tAST_Node *init=NULL, *cond=NULL, *inc=NULL, *code;
337 GetToken(Parser); // Eat 'for'
339 #if SUPPORT_BREAK_TAGS
340 if(LookAhead(Parser) == TOK_LT)
343 SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
344 tag = strndup(Parser->TokenStr, Parser->TokenLen);
345 SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
349 SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN);
351 if(LookAhead(Parser) != TOK_SEMICOLON)
352 init = Parse_DoExpr0(Parser);
354 SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON);
356 if(LookAhead(Parser) != TOK_SEMICOLON)
357 cond = Parse_DoExpr0(Parser);
359 SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON);
361 if(LookAhead(Parser) != TOK_PAREN_CLOSE)
362 inc = Parse_DoExpr0(Parser);
364 SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
366 code = Parse_DoCodeBlock(Parser);
367 ret = AST_NewLoop(Parser, tag, init, 0, cond, inc, code);
374 const char *tag = "";
375 tAST_Node *code, *cond;
376 GetToken(Parser); // Eat 'do'
378 #if SUPPORT_BREAK_TAGS
379 if(LookAhead(Parser) == TOK_LT)
382 SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
383 tag = strndup(Parser->TokenStr, Parser->TokenLen);
384 SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
388 code = Parse_DoCodeBlock(Parser);
389 SyntaxAssert( Parser, GetToken(Parser), TOK_RWD_WHILE );
390 SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_OPEN );
391 cond = Parse_DoExpr0(Parser);
392 SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_CLOSE );
393 ret = AST_NewLoop(Parser, tag, AST_NewNop(Parser), 1, cond, AST_NewNop(Parser), code);
398 const char *tag = "";
399 tAST_Node *code, *cond;
400 GetToken(Parser); // Eat 'while'
402 #if SUPPORT_BREAK_TAGS
403 if(LookAhead(Parser) == TOK_LT)
406 SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
407 tag = strndup(Parser->TokenStr, Parser->TokenLen);
408 SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
412 SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_OPEN );
413 cond = Parse_DoExpr0(Parser);
414 SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_CLOSE );
415 code = Parse_DoCodeBlock(Parser);
416 ret = AST_NewLoop(Parser, tag, AST_NewNop(Parser), 0, cond, AST_NewNop(Parser), code);
421 case TOKEN_GROUP_TYPES:
425 TOKEN_GET_DATATYPE(type, Parser->Token);
427 SyntaxAssert(Parser, GetToken(Parser), TOK_VARIABLE);
429 ret = Parse_GetVarDef(Parser, type);
436 ret = Parse_DoExpr0(Parser);
440 SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON );
445 * \brief Get a variable definition
447 tAST_Node *Parse_GetVarDef(tParser *Parser, int Type)
449 char name[Parser->TokenLen];
452 SyntaxAssert(Parser, Parser->Token, TOK_VARIABLE);
454 // copy the name (trimming the $)
455 memcpy(name, Parser->TokenStr+1, Parser->TokenLen-1);
456 name[Parser->TokenLen-1] = 0;
457 // Define the variable
458 ret = AST_NewDefineVar(Parser, Type, name);
460 while( LookAhead(Parser) == TOK_SQUARE_OPEN )
464 node = Parse_DoExpr0(Parser);
469 AST_AppendNode(ret, node);
470 SyntaxAssert(Parser, GetToken(Parser), TOK_SQUARE_CLOSE);
473 if( LookAhead(Parser) == TOK_ASSIGN )
476 ret->DefVar.InitialValue = Parse_DoExpr0(Parser);
477 if(!ret->DefVar.InitialValue) {
487 * \brief Assignment Operations
489 tAST_Node *Parse_DoExpr0(tParser *Parser)
491 #define _next Parse_DoExpr1
492 tAST_Node *ret = _next(Parser);
498 switch(GetToken(Parser))
501 ret = AST_NewAssign(Parser, NODETYPE_NOP, ret, _next(Parser));
504 ret = AST_NewAssign(Parser, NODETYPE_DIVIDE, ret, _next(Parser));
507 ret = AST_NewAssign(Parser, NODETYPE_MULTIPLY, ret, _next(Parser));
509 case TOK_ASSIGN_PLUS:
510 ret = AST_NewAssign(Parser, NODETYPE_ADD, ret, _next(Parser));
512 case TOK_ASSIGN_MINUS:
513 ret = AST_NewAssign(Parser, NODETYPE_SUBTRACT, ret, _next(Parser));
517 printf("Parse_DoExpr0: Parser->Token = %i\n", Parser->Token);
529 * \brief Logical/Boolean Operators
531 tAST_Node *Parse_DoExpr1(tParser *Parser)
533 #define _next Parse_DoExpr2
534 tAST_Node *ret = _next(Parser);
539 switch(GetToken(Parser))
542 ret = AST_NewBinOp(Parser, NODETYPE_LOGICALAND, ret, _next(Parser));
545 ret = AST_NewBinOp(Parser, NODETYPE_LOGICALOR, ret, _next(Parser));
548 ret = AST_NewBinOp(Parser, NODETYPE_LOGICALXOR, ret, _next(Parser));
560 // --------------------
561 // Expression 2 - Comparison Operators
562 // --------------------
563 tAST_Node *Parse_DoExpr2(tParser *Parser)
565 #define _next Parse_DoExpr3
566 tAST_Node *ret = _next(Parser);
572 switch(GetToken(Parser))
575 ret = AST_NewBinOp(Parser, NODETYPE_EQUALS, ret, _next(Parser));
578 ret = AST_NewBinOp(Parser, NODETYPE_LESSTHAN, ret, _next(Parser));
581 ret = AST_NewBinOp(Parser, NODETYPE_GREATERTHAN, ret, _next(Parser));
584 ret = AST_NewBinOp(Parser, NODETYPE_LESSTHANEQUAL, ret, _next(Parser));
587 ret = AST_NewBinOp(Parser, NODETYPE_GREATERTHANEQUAL, ret, _next(Parser));
600 * \brief Bitwise Operations
602 tAST_Node *Parse_DoExpr3(tParser *Parser)
604 #define _next Parse_DoExpr4
605 tAST_Node *ret = _next(Parser);
611 switch(GetToken(Parser))
614 ret = AST_NewBinOp(Parser, NODETYPE_BWOR, ret, _next(Parser));
617 ret = AST_NewBinOp(Parser, NODETYPE_BWAND, ret, _next(Parser));
620 ret = AST_NewBinOp(Parser, NODETYPE_BWXOR, ret, _next(Parser));
632 // --------------------
633 // Expression 4 - Shifts
634 // --------------------
635 tAST_Node *Parse_DoExpr4(tParser *Parser)
637 #define _next Parse_DoExpr5
638 tAST_Node *ret = _next(Parser);
643 switch(GetToken(Parser))
646 ret = AST_NewBinOp(Parser, NODETYPE_BITSHIFTLEFT, ret, _next(Parser));
649 ret = AST_NewBinOp(Parser, NODETYPE_BITSHIFTRIGHT, ret, _next(Parser));
662 // --------------------
663 // Expression 5 - Arithmatic
664 // --------------------
665 tAST_Node *Parse_DoExpr5(tParser *Parser)
667 #define _next Parse_DoExpr6
668 tAST_Node *ret = _next(Parser);
671 // While loop is added to ensure that the evaluation order ends up as
673 // E.g. a + b + c + d ends up as (((a + b) + c) + d) for casting
676 switch(GetToken(Parser))
679 ret = AST_NewBinOp(Parser, NODETYPE_ADD, ret, _next(Parser));
682 ret = AST_NewBinOp(Parser, NODETYPE_SUBTRACT, ret, _next(Parser));
695 // --------------------
696 // Expression 6 - Multiplcation & Division
697 // --------------------
698 tAST_Node *Parse_DoExpr6(tParser *Parser)
700 #define _next Parse_DoExpr7
701 tAST_Node *ret = _next(Parser);
706 switch(GetToken(Parser))
709 ret = AST_NewBinOp(Parser, NODETYPE_MULTIPLY, ret, _next(Parser));
712 ret = AST_NewBinOp(Parser, NODETYPE_DIVIDE, ret, _next(Parser));
725 // --------------------
726 // Expression 7 - Right Unary Operations
727 // --------------------
728 tAST_Node *Parse_DoExpr7(tParser *Parser)
730 tAST_Node *ret = Parse_DoExpr8(Parser);
732 switch(GetToken(Parser))
735 ret = AST_NewUniOp(Parser, NODETYPE_POSTINC, ret);
738 ret = AST_NewUniOp(Parser, NODETYPE_POSTDEC, ret);
747 // --------------------
748 // Expression 8 - Left Unary Operations
749 // --------------------
750 tAST_Node *Parse_DoExpr8(tParser *Parser)
752 switch(GetToken(Parser))
755 return AST_NewAssign(Parser, NODETYPE_ADD, Parse_DoExpr8(Parser), AST_NewInteger(Parser, 1));
757 return AST_NewAssign(Parser, NODETYPE_SUBTRACT, Parse_DoExpr8(Parser), AST_NewInteger(Parser, 1));
759 return AST_NewUniOp(Parser, NODETYPE_NEGATE, Parse_DoExpr8(Parser));
761 return AST_NewUniOp(Parser, NODETYPE_LOGICALNOT, Parse_DoExpr8(Parser));
763 return AST_NewUniOp(Parser, NODETYPE_BWNOT, Parse_DoExpr8(Parser));
766 return Parse_DoParen(Parser);
770 // --------------------
771 // 2nd Last Expression - Parens
772 // --------------------
773 tAST_Node *Parse_DoParen(tParser *Parser)
776 printf("Parse_DoParen: (Parser=%p)\n", Parser);
778 if(LookAhead(Parser) == TOK_PAREN_OPEN)
784 // TODO: Handle casts here
785 switch(LookAhead(Parser))
787 case TOKEN_GROUP_TYPES:
789 TOKEN_GET_DATATYPE(type, Parser->Token);
790 SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
791 ret = AST_NewCast(Parser, type, Parse_DoParen(Parser));
794 ret = Parse_DoExpr0(Parser);
795 SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
801 return Parse_DoValue(Parser);
804 // --------------------
805 // Last Expression - Value
806 // --------------------
807 tAST_Node *Parse_DoValue(tParser *Parser)
809 int tok = LookAhead(Parser);
812 printf("Parse_DoValue: tok = %i\n", tok);
818 return Parse_GetString(Parser);
820 return Parse_GetNumeric(Parser);
824 return AST_NewReal( Parser, atof(Parser->TokenStr) );
827 return Parse_GetIdent(Parser, 0);
829 return Parse_GetVariable(Parser);
832 return AST_NewNop(Parser); // NODETYPE_NOP returns NULL
835 return Parse_GetIdent(Parser, 1);
838 fprintf(stderr, "Syntax Error: Unexpected %s on line %i, Expected TOK_T_VALUE\n",
839 csaTOKEN_NAMES[tok], Parser->CurLine);
840 longjmp( Parser->JmpTarget, -1 );
845 * \brief Get a string
847 tAST_Node *Parse_GetString(tParser *Parser)
854 char data[ Parser->TokenLen - 2 ];
857 for( i = 1; i < Parser->TokenLen - 1; i++ )
859 if( Parser->TokenStr[i] == '\\' ) {
861 switch( Parser->TokenStr[i] )
863 case 'n': data[j++] = '\n'; break;
864 case 'r': data[j++] = '\r'; break;
867 // TODO: Error/Warning?
872 data[j++] = Parser->TokenStr[i];
876 // TODO: Parse Escape Codes
877 ret = AST_NewString( Parser, data, j );
883 * \brief Get a numeric value
885 tAST_Node *Parse_GetNumeric(tParser *Parser)
889 SyntaxAssert( Parser, GetToken( Parser ), TOK_INTEGER );
890 pos = Parser->TokenStr;
891 //printf("pos = %p, *pos = %c\n", pos, *pos);
901 if( '0' <= *pos && *pos <= '9' ) {
905 if( 'A' <= *pos && *pos <= 'F' ) {
906 value += *pos - 'A' + 10;
909 if( 'a' <= *pos && *pos <= 'f' ) {
910 value += *pos - 'a' + 10;
917 while( '0' <= *pos && *pos <= '7' ) {
918 value = value*8 + *pos - '0';
924 while( '0' <= *pos && *pos <= '9' ) {
925 value = value*10 + *pos - '0';
930 return AST_NewInteger( Parser, value );
934 * \brief Get a variable
936 tAST_Node *Parse_GetVariable(tParser *Parser)
939 SyntaxAssert( Parser, GetToken(Parser), TOK_VARIABLE );
941 char name[Parser->TokenLen];
942 memcpy(name, Parser->TokenStr+1, Parser->TokenLen-1);
943 name[Parser->TokenLen-1] = 0;
944 ret = AST_NewVariable( Parser, name );
946 printf("Parse_GetVariable: name = '%s'\n", name);
952 if( Parser->Token == TOK_SQUARE_OPEN )
954 ret = AST_NewBinOp(Parser, NODETYPE_INDEX, ret, Parse_DoExpr0(Parser));
955 SyntaxAssert(Parser, GetToken(Parser), TOK_SQUARE_CLOSE);
958 if( Parser->Token == TOK_ELEMENT )
960 SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
962 if( LookAhead(Parser) == TOK_PAREN_OPEN )
964 char name[Parser->TokenLen+1];
965 memcpy(name, Parser->TokenStr, Parser->TokenLen);
966 name[Parser->TokenLen] = 0;
967 ret = AST_NewMethodCall(Parser, ret, name);
968 GetToken(Parser); // Eat the '('
970 if( GetToken(Parser) != TOK_PAREN_CLOSE )
974 AST_AppendFunctionCallArg( ret, Parse_DoExpr0(Parser) );
975 } while(GetToken(Parser) == TOK_COMMA);
976 SyntaxAssert( Parser, Parser->Token, TOK_PAREN_CLOSE );
983 char name[Parser->TokenLen];
984 memcpy(name, Parser->TokenStr+1, Parser->TokenLen-1);
985 name[Parser->TokenLen-1] = 0;
986 ret = AST_NewClassElement(Parser, ret, name);
998 * \brief Get an identifier (constant or function call)
1000 tAST_Node *Parse_GetIdent(tParser *Parser, int bObjectCreate)
1002 tAST_Node *ret = NULL;
1004 SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
1005 name = strndup( Parser->TokenStr, Parser->TokenLen );
1008 if( GetToken(Parser) == TOK_SCOPE )
1010 ret = AST_NewScopeDereference( Parser, name, Parse_GetIdent(Parser, bObjectCreate) );
1017 if( GetToken(Parser) == TOK_PAREN_OPEN )
1020 printf("Parse_GetIdent: Calling '%s'\n", name);
1024 ret = AST_NewCreateObject( Parser, name );
1026 ret = AST_NewFunctionCall( Parser, name );
1028 if( GetToken(Parser) != TOK_PAREN_CLOSE )
1033 printf(" Parse_GetIdent: Argument\n");
1035 AST_AppendFunctionCallArg( ret, Parse_DoExpr0(Parser) );
1036 } while(GetToken(Parser) == TOK_COMMA);
1037 SyntaxAssert( Parser, Parser->Token, TOK_PAREN_CLOSE );
1039 printf(" Parse_GetIdent: All arguments parsed\n");
1045 // Runtime Constant / Variable (When implemented)
1047 printf("Parse_GetIdent: Referencing '%s'\n", name);
1050 if( bObjectCreate ) // Void constructor (TODO: Should this be an error?)
1051 ret = AST_NewCreateObject( Parser, name );
1053 ret = AST_NewConstant( Parser, name );
1061 void SyntaxError(tParser *Parser, int bFatal, const char *Message, ...)
1064 va_start(args, Message);
1065 fprintf(stderr, "%s:%i: error: ", Parser->Filename, Parser->CurLine);
1066 vfprintf(stderr, Message, args);
1067 fprintf(stderr, "\n");
1071 //longjmp(Parser->JmpTarget, -1);
1072 Parser->ErrorHit = 1;