summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/slang/slparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/slang/slparse.c')
-rw-r--r--mdk-stage1/slang/slparse.c1970
1 files changed, 0 insertions, 1970 deletions
diff --git a/mdk-stage1/slang/slparse.c b/mdk-stage1/slang/slparse.c
deleted file mode 100644
index bc709d1fb..000000000
--- a/mdk-stage1/slang/slparse.c
+++ /dev/null
@@ -1,1970 +0,0 @@
-/* Copyright (c) 1998, 1999, 2001 John E. Davis
- * This file is part of the S-Lang library.
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Perl Artistic License.
- */
-
-#include "slinclud.h"
-
-#include "slang.h"
-#include "_slang.h"
-
-static SLang_Load_Type *LLT;
-int _SLang_Compile_Line_Num_Info;
-
-static void free_token (_SLang_Token_Type *t)
-{
- register unsigned int nrefs = t->num_refs;
-
- if (nrefs == 0)
- return;
-
- if (nrefs == 1)
- {
- if (t->free_sval_flag)
- {
- if (t->type == BSTRING_TOKEN)
- SLbstring_free (t->v.b_val);
- else
- _SLfree_hashed_string (t->v.s_val, strlen (t->v.s_val), t->hash);
- t->v.s_val = NULL;
- }
- }
-
- t->num_refs = nrefs - 1;
-}
-
-static void init_token (_SLang_Token_Type *t)
-{
- memset ((char *) t, 0, sizeof (_SLang_Token_Type));
-#if _SLANG_HAS_DEBUG_CODE
- t->line_number = -1;
-#endif
-}
-
-/* Allow room for one push back of a token. This is necessary for
- * multiple assignment.
- */
-static unsigned int Use_Next_Token;
-static _SLang_Token_Type Next_Token;
-#if _SLANG_HAS_DEBUG_CODE
-static int Last_Line_Number = -1;
-#endif
-
-static int unget_token (_SLang_Token_Type *ctok)
-{
- if (SLang_Error)
- return -1;
- if (Use_Next_Token != 0)
- {
- _SLparse_error ("unget_token failed", ctok, 0);
- return -1;
- }
-
- Use_Next_Token++;
- Next_Token = *ctok;
- init_token (ctok);
- return 0;
-}
-
-static int get_token (_SLang_Token_Type *ctok)
-{
- if (ctok->num_refs)
- free_token (ctok);
-
- if (Use_Next_Token)
- {
- Use_Next_Token--;
- *ctok = Next_Token;
- return ctok->type;
- }
-
- return _SLget_token (ctok);
-}
-
-static int compile_token (_SLang_Token_Type *t)
-{
-#if _SLANG_HAS_DEBUG_CODE
- if (_SLang_Compile_Line_Num_Info
- && (t->line_number != Last_Line_Number)
- && (t->line_number != -1))
- {
- _SLang_Token_Type tok;
- tok.type = LINE_NUM_TOKEN;
- tok.v.long_val = Last_Line_Number = t->line_number;
- (*_SLcompile_ptr) (&tok);
- }
-#endif
- (*_SLcompile_ptr) (t);
- return 0;
-}
-
-typedef struct
-{
-#define USE_PARANOID_MAGIC 0
-#if USE_PARANOID_MAGIC
- unsigned long magic;
-#endif
- _SLang_Token_Type *stack;
- unsigned int len;
- unsigned int size;
-}
-Token_List_Type;
-
-#define MAX_TOKEN_LISTS 16
-static Token_List_Type Token_List_Stack [MAX_TOKEN_LISTS];
-static unsigned int Token_List_Stack_Depth = 0;
-static Token_List_Type *Token_List = NULL;
-
-static void init_token_list (Token_List_Type *t)
-{
- t->size = 0;
- t->len = 0;
- t->stack = NULL;
-#if USE_PARANOID_MAGIC
- t->magic = 0xABCDEF12;
-#endif
-}
-
-static void free_token_list (Token_List_Type *t)
-{
- _SLang_Token_Type *s;
-
- if (t == NULL)
- return;
-#if USE_PARANOID_MAGIC
- if (t->magic != 0xABCDEF12)
- {
- SLang_doerror ("Magic error.");
- return;
- }
-#endif
- s = t->stack;
- if (s != NULL)
- {
- _SLang_Token_Type *smax = s + t->len;
- while (s != smax)
- {
- if (s->num_refs) free_token (s);
- s++;
- }
-
- SLfree ((char *) t->stack);
- }
-
- memset ((char *) t, 0, sizeof (Token_List_Type));
-}
-
-static Token_List_Type *push_token_list (void)
-{
- if (Token_List_Stack_Depth == MAX_TOKEN_LISTS)
- {
- _SLparse_error ("Token list stack size exceeded", NULL, 0);
- return NULL;
- }
-
- Token_List = Token_List_Stack + Token_List_Stack_Depth;
- Token_List_Stack_Depth++;
- init_token_list (Token_List);
- return Token_List;
-}
-
-static int pop_token_list (int do_free)
-{
- if (Token_List_Stack_Depth == 0)
- {
- if (SLang_Error == 0)
- _SLparse_error ("Token list stack underflow", NULL, 0);
- return -1;
- }
- Token_List_Stack_Depth--;
-
- if (do_free) free_token_list (Token_List);
-
- if (Token_List_Stack_Depth != 0)
- Token_List = Token_List_Stack + (Token_List_Stack_Depth - 1);
- else
- Token_List = NULL;
-
- return 0;
-}
-
-static int check_token_list_space (Token_List_Type *t, unsigned int delta_size)
-{
- _SLang_Token_Type *st;
- unsigned int len;
-#if USE_PARANOID_MAGIC
- if (t->magic != 0xABCDEF12)
- {
- SLang_doerror ("Magic error.");
- return -1;
- }
-#endif
- len = t->len + delta_size;
- if (len <= t->size) return 0;
-
- if (delta_size < 4)
- {
- delta_size = 4;
- len = t->len + delta_size;
- }
-
- st = (_SLang_Token_Type *) SLrealloc((char *) t->stack,
- len * sizeof(_SLang_Token_Type));
- if (st == NULL)
- {
- _SLparse_error ("Malloc error", NULL, 0);
- return -1;
- }
-
- memset ((char *) (st + t->len), 0, delta_size);
-
- t->stack = st;
- t->size = len;
- return 0;
-}
-
-static int append_token (_SLang_Token_Type *t)
-{
- if (-1 == check_token_list_space (Token_List, 1))
- return -1;
-
- Token_List->stack [Token_List->len] = *t;
- Token_List->len += 1;
- t->num_refs = 0; /* stealing it */
- return 0;
-}
-
-static int append_token_of_type (unsigned char t)
-{
- _SLang_Token_Type *tok;
-
- if (-1 == check_token_list_space (Token_List, 1))
- return -1;
-
- /* The memset when the list was created ensures that the other fields
- * are properly initialized.
- */
- tok = Token_List->stack + Token_List->len;
- init_token (tok);
- tok->type = t;
- Token_List->len += 1;
- return 0;
-}
-
-static _SLang_Token_Type *get_last_token (void)
-{
- unsigned int len;
-
- if ((Token_List == NULL)
- || (0 == (len = Token_List->len)))
- return NULL;
-
- len--;
- return Token_List->stack + len;
-}
-
-/* This function does NOT free the list. */
-static int compile_token_list_with_fun (int dir, Token_List_Type *list,
- int (*f)(_SLang_Token_Type *))
-{
- _SLang_Token_Type *t0, *t1;
-
- if (list == NULL)
- return -1;
-
- if (f == NULL)
- f = compile_token;
-
- t0 = list->stack;
- t1 = t0 + list->len;
-
- if (dir < 0)
- {
- /* backwards */
-
- while ((SLang_Error == 0) && (t1 > t0))
- {
- t1--;
- (*f) (t1);
- }
- return 0;
- }
-
- /* forward */
- while ((SLang_Error == 0) && (t0 < t1))
- {
- (*f) (t0);
- t0++;
- }
- return 0;
-}
-
-static int compile_token_list (void)
-{
- if (Token_List == NULL)
- return -1;
-
- compile_token_list_with_fun (1, Token_List, NULL);
- pop_token_list (1);
- return 0;
-}
-
-/* Take all elements in the list from pos2 to the end and exchange them
- * with the elements at pos1, e.g.,
- * ...ABCDEabc ==> ...abcABCDE
- * where pos1 denotes A and pos2 denotes a.
- */
-static int token_list_element_exchange (unsigned int pos1, unsigned int pos2)
-{
- _SLang_Token_Type *s, *s1, *s2;
- unsigned int len, nloops;
-
- if (Token_List == NULL)
- return -1;
-
- s = Token_List->stack;
- len = Token_List->len;
-
- if ((s == NULL) || (len == 0)
- || (pos2 >= len))
- return -1;
-
- /* This may not be the most efficient algorithm but the number to swap
- * is most-likely going to be small, e.g, 3
- * The algorithm is to rotate the list. The particular rotation
- * direction was chosen to make insert_token fast.
- * It works like:
- * @ ABCabcde --> BCabcdeA --> CabcdeAB --> abcdefAB
- * which is optimal for Abcdef sequence produced by function calls.
- *
- * Profiling indicates that nloops is almost always 1, whereas the inner
- * loop can loop many times (e.g., 9 times).
- */
-
- s2 = s + (len - 1);
- s1 = s + pos1;
- nloops = pos2 - pos1;
-
- while (nloops)
- {
- _SLang_Token_Type save;
-
- s = s1;
- save = *s;
-
- while (s < s2)
- {
- *s = *(s + 1);
- s++;
- }
- *s = save;
-
- nloops--;
- }
- return 0;
-}
-
-#if 0
-static int insert_token (_SLang_Token_Type *t, unsigned int pos)
-{
- if (-1 == append_token (t))
- return -1;
-
- return token_list_element_exchange (pos, Token_List->len - 1);
-}
-#endif
-static void compile_token_of_type (unsigned char t)
-{
- _SLang_Token_Type tok;
-
-#if _SLANG_HAS_DEBUG_CODE
- tok.line_number = -1;
-#endif
- tok.type = t;
- compile_token(&tok);
-}
-
-static void statement (_SLang_Token_Type *);
-static void compound_statement (_SLang_Token_Type *);
-static void expression_with_parenthesis (_SLang_Token_Type *);
-static void handle_semicolon (_SLang_Token_Type *);
-static void statement_list (_SLang_Token_Type *);
-static void variable_list (_SLang_Token_Type *, unsigned char);
-static void struct_declaration (_SLang_Token_Type *);
-static void define_function_args (_SLang_Token_Type *);
-static void typedef_definition (_SLang_Token_Type *);
-static void function_args_expression (_SLang_Token_Type *, int);
-static void expression (_SLang_Token_Type *);
-static void expression_with_commas (_SLang_Token_Type *, int);
-static void simple_expression (_SLang_Token_Type *);
-static void unary_expression (_SLang_Token_Type *);
-static void postfix_expression (_SLang_Token_Type *);
-static int check_for_lvalue (unsigned char, _SLang_Token_Type *);
-/* static void primary_expression (_SLang_Token_Type *); */
-static void block (_SLang_Token_Type *);
-static void inline_array_expression (_SLang_Token_Type *);
-static void array_index_expression (_SLang_Token_Type *);
-static void do_multiple_assignment (_SLang_Token_Type *);
-static void try_multiple_assignment (_SLang_Token_Type *);
-#if 0
-static void not_implemented (char *what)
-{
- char err [256];
- sprintf (err, "Expression not implemented: %s", what);
- _SLparse_error (err, NULL, 0);
-}
-#endif
-static void rpn_parse_line (_SLang_Token_Type *tok)
-{
- do
- {
- /* multiple RPN tokens possible when the file looks like:
- * . <end of line>
- * . <end of line>
- */
- if (tok->type != RPN_TOKEN)
- compile_token (tok);
- free_token (tok);
- }
- while (EOF_TOKEN != _SLget_rpn_token (tok));
-}
-
-static int get_identifier_token (_SLang_Token_Type *tok)
-{
- if (IDENT_TOKEN == get_token (tok))
- return IDENT_TOKEN;
-
- _SLparse_error ("Expecting identifier", tok, 0);
- return tok->type;
-}
-
-static void define_function (_SLang_Token_Type *ctok, unsigned char type)
-{
- _SLang_Token_Type fname;
-
- switch (type)
- {
- case STATIC_TOKEN:
- type = DEFINE_STATIC_TOKEN;
- break;
-
- case PUBLIC_TOKEN:
- type = DEFINE_PUBLIC_TOKEN;
- break;
-
- case PRIVATE_TOKEN:
- type = DEFINE_PRIVATE_TOKEN;
- }
-
- init_token (&fname);
- if (IDENT_TOKEN != get_identifier_token (&fname))
- {
- free_token (&fname);
- return;
- }
-
- compile_token_of_type(OPAREN_TOKEN);
- get_token (ctok);
- define_function_args (ctok);
- compile_token_of_type(FARG_TOKEN);
-
- if (ctok->type == OBRACE_TOKEN)
- compound_statement(ctok);
-
- else if (ctok->type != SEMICOLON_TOKEN)
- {
- _SLparse_error("Expecting {", ctok, 0);
- free_token (&fname);
- return;
- }
-
- fname.type = type;
- compile_token (&fname);
- free_token (&fname);
-}
-
-/* statement:
- * compound-statement
- * if ( expression ) statement
- * if ( expression ) statement else statement
- * !if ( expression ) statement
- * loop ( expression ) statement
- * _for ( expression ) statement
- * foreach ( expression ) statement
- * foreach (expression ) using (expression-list) statement
- * while ( expression ) statement
- * do statement while (expression) ;
- * for ( expressionopt ; expressionopt ; expressionopt ) statement
- * ERROR_BLOCK statement
- * EXIT_BLOCK statement
- * USER_BLOCK0 statement
- * USER_BLOCK1 statement
- * USER_BLOCK2 statement
- * USER_BLOCK3 statement
- * USER_BLOCK4 statement
- * forever statement
- * break ;
- * continue ;
- * return expressionopt ;
- * variable variable-list ;
- * struct struct-decl ;
- * define identifier function-args ;
- * define identifier function-args compound-statement
- * switch ( expression ) statement
- * rpn-line
- * at-line
- * push ( expression )
- * ( expression ) = expression ;
- * expression ;
- * expression :
- */
-
-/* Note: This function does not return with a new token. It is up to the
- * calling routine to handle that.
- */
-static void statement (_SLang_Token_Type *ctok)
-{
- unsigned char type;
-
- if (SLang_Error)
- return;
-
- LLT->parse_level += 1;
-
- switch (ctok->type)
- {
- case OBRACE_TOKEN:
- compound_statement (ctok);
- break;
-
- case IF_TOKEN:
- case IFNOT_TOKEN:
- type = ctok->type;
- get_token (ctok);
- expression_with_parenthesis (ctok);
- block (ctok);
-
- if (ELSE_TOKEN != get_token (ctok))
- {
- compile_token_of_type (type);
- unget_token (ctok);
- break;
- }
- get_token (ctok);
- block (ctok);
- if (type == IF_TOKEN) type = ELSE_TOKEN; else type = NOTELSE_TOKEN;
- compile_token_of_type (type);
- break;
-
- /* case IFNOT_TOKEN: */
- case LOOP_TOKEN:
- case _FOR_TOKEN:
- type = ctok->type;
- get_token (ctok);
- expression_with_parenthesis (ctok);
- block (ctok);
- compile_token_of_type (type);
- break;
-
- case FOREACH_TOKEN:
- get_token (ctok);
- expression_with_parenthesis (ctok);
-
- if (NULL == push_token_list ())
- break;
-
- append_token_of_type (ARG_TOKEN);
- if (ctok->type == USING_TOKEN)
- {
- if (OPAREN_TOKEN != get_token (ctok))
- {
- _SLparse_error ("Expected 'using ('", ctok, 0);
- break;
- }
- get_token (ctok);
- function_args_expression (ctok, 0);
- }
- append_token_of_type (EARG_TOKEN);
-
- compile_token_list ();
-
- block (ctok);
- compile_token_of_type (FOREACH_TOKEN);
- break;
-
- case WHILE_TOKEN:
- get_token (ctok);
- compile_token_of_type (OBRACE_TOKEN);
- expression_with_parenthesis (ctok);
- compile_token_of_type (CBRACE_TOKEN);
- block (ctok);
- compile_token_of_type (WHILE_TOKEN);
- break;
-
- case DO_TOKEN:
- get_token (ctok);
- block (ctok);
-
- if (WHILE_TOKEN != get_token (ctok))
- {
- _SLparse_error("Expecting while", ctok, 0);
- break;
- }
-
- get_token (ctok);
-
- compile_token_of_type (OBRACE_TOKEN);
- expression_with_parenthesis (ctok);
- compile_token_of_type (CBRACE_TOKEN);
- compile_token_of_type (DOWHILE_TOKEN);
- handle_semicolon (ctok);
- break;
-
- case FOR_TOKEN:
-
- /* Look for (exp_opt ; exp_opt ; exp_opt ) */
-
- if (OPAREN_TOKEN != get_token (ctok))
- {
- _SLparse_error("Expecting (.", ctok, 0);
- break;
- }
-
- if (NULL == push_token_list ())
- break;
-
- append_token_of_type (OBRACE_TOKEN);
- if (SEMICOLON_TOKEN != get_token (ctok))
- {
- expression (ctok);
- if (ctok->type != SEMICOLON_TOKEN)
- {
- _SLparse_error("Expecting ;", ctok, 0);
- break;
- }
- }
- append_token_of_type (CBRACE_TOKEN);
-
- append_token_of_type (OBRACE_TOKEN);
- if (SEMICOLON_TOKEN != get_token (ctok))
- {
- expression (ctok);
- if (ctok->type != SEMICOLON_TOKEN)
- {
- _SLparse_error("Expecting ;", ctok, 0);
- break;
- }
- }
- append_token_of_type (CBRACE_TOKEN);
-
- append_token_of_type (OBRACE_TOKEN);
- if (CPAREN_TOKEN != get_token (ctok))
- {
- expression (ctok);
- if (ctok->type != CPAREN_TOKEN)
- {
- _SLparse_error("Expecting ).", ctok, 0);
- break;
- }
- }
- append_token_of_type (CBRACE_TOKEN);
-
- compile_token_list ();
-
- get_token (ctok);
- block (ctok);
- compile_token_of_type (FOR_TOKEN);
- break;
-
- case ERRBLK_TOKEN:
- case EXITBLK_TOKEN:
- case USRBLK0_TOKEN:
- case USRBLK1_TOKEN:
- case USRBLK2_TOKEN:
- case USRBLK3_TOKEN:
- case USRBLK4_TOKEN:
- case FOREVER_TOKEN:
- type = ctok->type;
- get_token (ctok);
- block (ctok);
- compile_token_of_type (type);
- break;
-
- case BREAK_TOKEN:
- case CONT_TOKEN:
- compile_token_of_type (ctok->type);
- get_token (ctok);
- handle_semicolon (ctok);
- break;
-
- case RETURN_TOKEN:
- if (SEMICOLON_TOKEN != get_token (ctok))
- {
- if (NULL == push_token_list ())
- break;
-
- expression (ctok);
-
- if (ctok->type != SEMICOLON_TOKEN)
- {
- _SLparse_error ("Expecting ;", ctok, 0);
- break;
- }
- compile_token_list ();
- }
- compile_token_of_type (RETURN_TOKEN);
- handle_semicolon (ctok);
- break;
-
- case STATIC_TOKEN:
- case PRIVATE_TOKEN:
- case PUBLIC_TOKEN:
- type = ctok->type;
- get_token (ctok);
- if (ctok->type == VARIABLE_TOKEN)
- {
- get_token (ctok);
- variable_list (ctok, type);
- handle_semicolon (ctok);
- break;
- }
- if (ctok->type == DEFINE_TOKEN)
- {
- define_function (ctok, type);
- break;
- }
- _SLparse_error ("Expecting 'variable' or 'define'", ctok, 0);
- break;
-
- case VARIABLE_TOKEN:
- get_token (ctok);
- variable_list (ctok, OBRACKET_TOKEN);
- handle_semicolon (ctok);
- break;
-
- case TYPEDEF_TOKEN:
- get_token (ctok);
- if (NULL == push_token_list ())
- break;
- typedef_definition (ctok);
- compile_token_list ();
-
- handle_semicolon (ctok);
- break;
-
- case DEFINE_TOKEN:
- define_function (ctok, DEFINE_TOKEN);
- break;
-
- case SWITCH_TOKEN:
- get_token (ctok);
- expression_with_parenthesis (ctok);
-
- while ((SLang_Error == 0)
- && (OBRACE_TOKEN == ctok->type))
- {
- compile_token_of_type (OBRACE_TOKEN);
- compound_statement (ctok);
- compile_token_of_type (CBRACE_TOKEN);
- get_token (ctok);
- }
- compile_token_of_type (SWITCH_TOKEN);
- unget_token (ctok);
- break;
-
- case EOF_TOKEN:
- break;
-#if 0
- case PUSH_TOKEN:
- get_token (ctok);
- expression_list_with_parenthesis (ctok);
- handle_semicolon (ctok);
- break;
-#endif
-
- case SEMICOLON_TOKEN:
- handle_semicolon (ctok);
- break;
-
- case RPN_TOKEN:
- if (POUND_TOKEN == get_token (ctok))
- _SLcompile_byte_compiled ();
- else if (ctok->type != EOF_TOKEN)
- rpn_parse_line (ctok);
- break;
-
- case OPAREN_TOKEN: /* multiple assignment */
- try_multiple_assignment (ctok);
- if (ctok->type == COLON_TOKEN)
- compile_token_of_type (COLON_TOKEN);
- else handle_semicolon (ctok);
- break;
-
- default:
-
- if (NULL == push_token_list ())
- break;
-
- expression (ctok);
- compile_token_list ();
-
- if (ctok->type == COLON_TOKEN)
- compile_token_of_type (COLON_TOKEN);
- else handle_semicolon (ctok);
- break;
- }
-
- LLT->parse_level -= 1;
-}
-
-static void block (_SLang_Token_Type *ctok)
-{
- compile_token_of_type (OBRACE_TOKEN);
- statement (ctok);
- compile_token_of_type (CBRACE_TOKEN);
-}
-
-/*
- * statement-list:
- * statement
- * statement-list statement
- */
-static void statement_list (_SLang_Token_Type *ctok)
-{
- while ((SLang_Error == 0)
- && (ctok->type != CBRACE_TOKEN)
- && (ctok->type != EOF_TOKEN))
- {
- statement(ctok);
- get_token (ctok);
- }
-}
-
-/* compound-statement:
- * { statement-list }
- */
-static void compound_statement (_SLang_Token_Type *ctok)
-{
- /* ctok->type is OBRACE_TOKEN here */
- get_token (ctok);
- statement_list(ctok);
- if (CBRACE_TOKEN != ctok->type)
- {
- _SLparse_error ("Expecting '}'", ctok, 0);
- return;
- }
-}
-
-/* This function is only called from statement. */
-static void expression_with_parenthesis (_SLang_Token_Type *ctok)
-{
- if (ctok->type != OPAREN_TOKEN)
- {
- _SLparse_error("Expecting (", ctok, 0);
- return;
- }
-
- if (NULL == push_token_list ())
- return;
-
- get_token (ctok);
- expression (ctok);
-
- if (ctok->type != CPAREN_TOKEN)
- _SLparse_error("Expecting )", ctok, 0);
-
- compile_token_list ();
-
- get_token (ctok);
-}
-
-static void handle_semicolon (_SLang_Token_Type *ctok)
-{
- if ((ctok->type == SEMICOLON_TOKEN)
- || (ctok->type == EOF_TOKEN))
- return;
-
- _SLparse_error ("Expecting ;", ctok, 0);
-}
-
-void _SLparse_start (SLang_Load_Type *llt)
-{
- _SLang_Token_Type ctok;
- SLang_Load_Type *save_llt;
- unsigned int save_use_next_token;
- _SLang_Token_Type save_next_token;
- Token_List_Type *save_list;
-#if _SLANG_HAS_DEBUG_CODE
- int save_last_line_number = Last_Line_Number;
-
- Last_Line_Number = -1;
-#endif
- save_use_next_token = Use_Next_Token;
- save_next_token = Next_Token;
- save_list = Token_List;
- save_llt = LLT;
- LLT = llt;
-
- init_token (&Next_Token);
- Use_Next_Token = 0;
- init_token (&ctok);
- get_token (&ctok);
-
- llt->parse_level = 0;
- statement_list (&ctok);
-
- if ((SLang_Error == 0)
- && (ctok.type != EOF_TOKEN))
- _SLparse_error ("Parse ended prematurely", &ctok, 0);
-
-
- if (SLang_Error)
- {
- if (SLang_Error < 0) /* severe error */
- save_list = NULL;
-
- while (Token_List != save_list)
- {
- if (-1 == pop_token_list (1))
- break; /* ??? when would this happen? */
- }
- }
-
- free_token (&ctok);
- LLT = save_llt;
- if (Use_Next_Token)
- free_token (&Next_Token);
- Use_Next_Token = save_use_next_token;
- Next_Token = save_next_token;
-#if _SLANG_HAS_DEBUG_CODE
- Last_Line_Number = save_last_line_number;
-#endif
-}
-
-/* variable-list:
- * variable-decl
- * variable-decl variable-list
- *
- * variable-decl:
- * identifier
- * identifier = simple-expression
- */
-static void variable_list (_SLang_Token_Type *name_token, unsigned char variable_type)
-{
- int declaring;
- _SLang_Token_Type tok;
-
- if (name_token->type != IDENT_TOKEN)
- {
- _SLparse_error ("Expecting a variable name", name_token, 0);
- return;
- }
-
- declaring = 0;
- do
- {
- if (declaring == 0)
- {
- declaring = 1;
- compile_token_of_type (variable_type);
- }
-
- compile_token (name_token);
-
- init_token (&tok);
- if (ASSIGN_TOKEN == get_token (&tok))
- {
- compile_token_of_type (CBRACKET_TOKEN);
- declaring = 0;
-
- get_token (&tok);
-
- push_token_list ();
- simple_expression (&tok);
- compile_token_list ();
-
- name_token->type = _SCALAR_ASSIGN_TOKEN;
- compile_token (name_token);
- }
-
- free_token (name_token);
- *name_token = tok;
- }
- while ((name_token->type == COMMA_TOKEN)
- && (IDENT_TOKEN == get_token (name_token)));
-
- if (declaring) compile_token_of_type (CBRACKET_TOKEN);
-}
-
-/* struct-declaration:
- * struct { struct-field-list };
- *
- * struct-field-list:
- * struct-field-name , struct-field-list
- * struct-field-name
- *
- * Generates code: "field-name-1" ... "field-name-N" N STRUCT_TOKEN
- */
-static void struct_declaration (_SLang_Token_Type *ctok)
-{
- int n;
- _SLang_Token_Type num_tok;
-
- if (ctok->type != OBRACE_TOKEN)
- {
- _SLparse_error ("Expecting {", ctok, 0);
- return;
- }
-
- n = 0;
- while (IDENT_TOKEN == get_token (ctok))
- {
- n++;
- ctok->type = STRING_TOKEN;
- append_token (ctok);
- if (COMMA_TOKEN != get_token (ctok))
- break;
- }
-
- if (ctok->type != CBRACE_TOKEN)
- {
- _SLparse_error ("Expecting }", ctok, 0);
- return;
- }
- if (n == 0)
- {
- _SLparse_error ("struct requires at least 1 field", ctok, 0);
- return;
- }
-
- init_token (&num_tok);
- num_tok.type = INT_TOKEN;
- num_tok.v.long_val = n;
- append_token (&num_tok);
- append_token_of_type (STRUCT_TOKEN);
-
- get_token (ctok);
-}
-
-/* struct-declaration:
- * typedef struct { struct-field-list } Type_Name;
- *
- * struct-field-list:
- * struct-field-name , struct-field-list
- * struct-field-name
- *
- * Generates code: "field-name-1" ... "field-name-N" N STRUCT_TOKEN typedef
- */
-static void typedef_definition (_SLang_Token_Type *t)
-{
-
- if (t->type != STRUCT_TOKEN)
- {
- _SLparse_error ("Expecting `struct'", t, 0);
- return;
- }
- get_token (t);
-
- struct_declaration (t);
- if (t->type != IDENT_TOKEN)
- {
- _SLparse_error ("Expecting identifier", t, 0);
- return;
- }
-
- t->type = STRING_TOKEN;
- append_token (t);
- append_token_of_type (TYPEDEF_TOKEN);
-
- get_token (t);
-}
-
-/* function-args:
- * ( args-dec-opt )
- *
- * args-decl-opt:
- * identifier
- * args-decl , identifier
- */
-static void define_function_args (_SLang_Token_Type *ctok)
-{
- if (CPAREN_TOKEN == get_token (ctok))
- {
- get_token (ctok);
- return;
- }
-
- compile_token_of_type(OBRACKET_TOKEN);
-
- while ((SLang_Error == 0)
- && (ctok->type == IDENT_TOKEN))
- {
- compile_token (ctok);
- if (COMMA_TOKEN != get_token (ctok))
- break;
-
- get_token (ctok);
- }
-
- if (CPAREN_TOKEN != ctok->type)
- {
- _SLparse_error("Expecting )", ctok, 0);
- return;
- }
- compile_token_of_type(CBRACKET_TOKEN);
-
- get_token (ctok);
-}
-
-void try_multiple_assignment (_SLang_Token_Type *ctok)
-{
- /* This is called with ctok->type == OPAREN_TOKEN. We have no idea
- * what follows this. There are various possibilities such as:
- * @ () = x;
- * @ ( expression ) = x;
- * @ ( expression ) ;
- * @ ( expression ) OP expression;
- * @ ( expression ) [expression] = expression;
- * and only the first two constitute a multiple assignment. The last
- * two forms create the difficulty.
- *
- * Here is the plan. First parse (expression) and then check next token.
- * If it is an equal operator, then it will be parsed as a multiple
- * assignment. In fact, that is the easy part.
- *
- * The hard part stems from the fact that by parsing (expression), we
- * have effectly truncated the parse if (expression) is part of a binary
- * or unary expression. Somehow, the parsing must be resumed. The trick
- * here is to use a dummy literal that generates no code: NO_OP_LITERAL
- * Using it, we just call 'expression' and proceed.
- */
-
- if (NULL == push_token_list ())
- return;
-
- get_token (ctok);
-
- if (ctok->type != CPAREN_TOKEN)
- {
- expression_with_commas (ctok, 1);
- if (ctok->type != CPAREN_TOKEN)
- {
- _SLparse_error ("Expecting )", ctok, 0);
- return;
- }
- }
-
- switch (get_token (ctok))
- {
- case ASSIGN_TOKEN:
- case PLUSEQS_TOKEN:
- case MINUSEQS_TOKEN:
- case TIMESEQS_TOKEN:
- case DIVEQS_TOKEN:
- case BOREQS_TOKEN:
- case BANDEQS_TOKEN:
- do_multiple_assignment (ctok);
- pop_token_list (1);
- break;
-
- default:
- unget_token (ctok);
- ctok->type = NO_OP_LITERAL;
- expression (ctok);
- compile_token_list ();
- break;
- }
-}
-
-/* Note: expression never gets compiled directly. Rather, it gets
- * appended to the token list and then compiled by a calling
- * routine.
- */
-
-/* expression:
- * simple_expression
- * simple-expression , expression
- * <none>
- */
-static void expression_with_commas (_SLang_Token_Type *ctok, int save_comma)
-{
- while (SLang_Error == 0)
- {
- if (ctok->type != COMMA_TOKEN)
- {
- if (ctok->type == CPAREN_TOKEN)
- return;
-
- simple_expression (ctok);
-
- if (ctok->type != COMMA_TOKEN)
- break;
- }
- if (save_comma) append_token (ctok);
- get_token (ctok);
- }
-}
-
-static void expression (_SLang_Token_Type *ctok)
-{
- expression_with_commas (ctok, 0);
-}
-
-/* priority levels of binary operations */
-static unsigned char Binop_Level[] =
-{
-/* ADD_TOKEN */ 2,
-/* SUB_TOKEN */ 2,
-/* MUL_TOKEN */ 1,
-/* DIV_TOKEN */ 1,
-/* LT_TOKEN */ 4,
-/* LE_TOKEN */ 4,
-/* GT_TOKEN */ 4,
-/* GE_TOKEN */ 4,
-/* EQ_TOKEN */ 5,
-/* NE_TOKEN */ 5,
-/* AND_TOKEN */ 9,
-/* OR_TOKEN */ 10,
-/* MOD_TOKEN */ 1,
-/* BAND_TOKEN */ 6,
-/* SHL_TOKEN */ 3,
-/* SHR_TOKEN */ 3,
-/* BXOR_TOKEN */ 7,
-/* BOR_TOKEN */ 8,
-/* POUND_TOKEN */ 1 /* Matrix Multiplication */
-};
-
-/* % Note: simple-expression groups operators OP1 at same level. The
- * % actual implementation will not do this.
- * simple-expression:
- * unary-expression
- * binary-expression BINARY-OP unary-expression
- * andelse xxelse-expression-list
- * orelse xxelse-expression-list
- *
- * xxelse-expression-list:
- * { expression }
- * xxelse-expression-list { expression }
- * binary-expression:
- * unary-expression
- * unary-expression BINARY-OP binary-expression
- */
-static void simple_expression (_SLang_Token_Type *ctok)
-{
- unsigned char type;
- unsigned char op_stack [64];
- unsigned char level_stack [64];
- unsigned char level;
- unsigned int op_num;
-
- switch (ctok->type)
- {
- case ANDELSE_TOKEN:
- case ORELSE_TOKEN:
- type = ctok->type;
- if (OBRACE_TOKEN != get_token (ctok))
- {
- _SLparse_error ("Expecting '{'", ctok, 0);
- return;
- }
-
- while (ctok->type == OBRACE_TOKEN)
- {
- append_token (ctok);
- get_token (ctok);
- expression (ctok);
- if (CBRACE_TOKEN != ctok->type)
- {
- _SLparse_error("Expecting }", ctok, 0);
- return;
- }
- append_token (ctok);
- get_token (ctok);
- }
- append_token_of_type (type);
- return;
-
- /* avoid unary-expression if possible */
- case STRING_TOKEN:
- append_token (ctok);
- get_token (ctok);
- break;
-
- default:
- unary_expression (ctok);
- break;
- }
-
- if (SEMICOLON_TOKEN == (type = ctok->type))
- return;
-
- op_num = 0;
-
- while ((SLang_Error == 0)
- && (IS_BINARY_OP(type)))
- {
- level = Binop_Level[type - FIRST_BINARY_OP];
-
- while ((op_num > 0) && (level_stack [op_num - 1] <= level))
- append_token_of_type (op_stack [--op_num]);
-
- if (op_num >= sizeof (op_stack) - 1)
- {
- _SLparse_error ("Binary op stack overflow", ctok, 0);
- return;
- }
-
- op_stack [op_num] = type;
- level_stack [op_num] = level;
- op_num++;
-
- get_token (ctok);
- unary_expression (ctok);
- type = ctok->type;
- }
-
- while (op_num > 0)
- append_token_of_type(op_stack[--op_num]);
-}
-
-/* unary-expression:
- * postfix-expression
- * ++ postfix-expression
- * -- postfix-expression
- * case unary-expression
- * OP3 unary-expression
- * (OP3: + - ~ & not @)
- *
- * Note: This grammar permits: case case case WHATEVER
- */
-static void unary_expression (_SLang_Token_Type *ctok)
-{
- unsigned char save_unary_ops [16];
- unsigned int num_unary_ops;
- unsigned char type;
- _SLang_Token_Type *last_token;
-
- num_unary_ops = 0;
- while (SLang_Error == 0)
- {
- type = ctok->type;
-
- switch (type)
- {
- case PLUSPLUS_TOKEN:
- case MINUSMINUS_TOKEN:
- get_token (ctok);
- postfix_expression (ctok);
- check_for_lvalue (type, NULL);
- goto out_of_switch;
-
- case ADD_TOKEN:
- get_token (ctok); /* skip it-- it's unary here */
- break;
-
- case SUB_TOKEN:
- (void) get_token (ctok);
- if (IS_INTEGER_TOKEN (ctok->type))
- {
- ctok->v.long_val = -ctok->v.long_val;
- break;
- }
-
- if (num_unary_ops == 16)
- goto stack_overflow_error;
- save_unary_ops [num_unary_ops++] = CHS_TOKEN;
- break;
-
- case DEREF_TOKEN:
- case BNOT_TOKEN:
- case NOT_TOKEN:
- case CASE_TOKEN:
- if (num_unary_ops == 16)
- goto stack_overflow_error;
-
- save_unary_ops [num_unary_ops++] = type;
- get_token (ctok);
- break;
-
- /* Try to avoid ->postfix_expression->primary_expression
- * subroutine calls.
- */
- case STRING_TOKEN:
- append_token (ctok);
- get_token (ctok);
- goto out_of_switch;
-
- default:
- postfix_expression (ctok);
- goto out_of_switch;
- }
- }
-
- out_of_switch:
- if (num_unary_ops == 0)
- return;
-
- if ((DEREF_TOKEN == save_unary_ops[num_unary_ops - 1])
- && (NULL != (last_token = get_last_token ()))
- && (IS_ASSIGN_TOKEN(last_token->type)))
- {
- /* FIXME: Priority=medium
- * This needs generalized so that things like @a.y = 1 will work properly.
- */
- if ((num_unary_ops != 1)
- || (last_token->type != _SCALAR_ASSIGN_TOKEN))
- {
- SLang_verror (SL_NOT_IMPLEMENTED,
- "Only derefence assignments to simple variables are possible");
- return;
- }
-
- last_token->type += (_DEREF_ASSIGN_TOKEN - _SCALAR_ASSIGN_TOKEN);
- return;
- }
-
- while (num_unary_ops)
- {
- num_unary_ops--;
- append_token_of_type (save_unary_ops [num_unary_ops]);
- }
- return;
-
- stack_overflow_error:
- _SLparse_error ("Too many unary operators.", ctok, 0);
-}
-
-static int combine_namespace_tokens (_SLang_Token_Type *a, _SLang_Token_Type *b)
-{
- char *sa, *sb, *sc;
- unsigned int lena, lenb;
- unsigned long hash;
-
- /* This is somewhat of a hack. Combine the TWO identifier names
- * (NAMESPACE) and (name) into the form NAMESPACE->name. Then when the
- * byte compiler compiles the object it will not be found. It will then
- * check for this hack and make the appropriate namespace lookup.
- */
-
- sa = a->v.s_val;
- sb = b->v.s_val;
-
- lena = strlen (sa);
- lenb = strlen (sb);
-
- sc = SLmalloc (lena + lenb + 3);
- if (sc == NULL)
- return -1;
-
- strcpy (sc, sa);
- strcpy (sc + lena, "->");
- strcpy (sc + lena + 2, sb);
-
- sb = _SLstring_make_hashed_string (sc, lena + lenb + 2, &hash);
- SLfree (sc);
- if (sb == NULL)
- return -1;
-
- /* I can free this string because no other token should be referencing it.
- * (num_refs == 1).
- */
- _SLfree_hashed_string (sa, lena, a->hash);
- a->v.s_val = sb;
- a->hash = hash;
-
- return 0;
-}
-
-static void append_identifier_token (_SLang_Token_Type *ctok)
-{
- _SLang_Token_Type *last_token;
-
- append_token (ctok);
-
- if (NAMESPACE_TOKEN != get_token (ctok))
- return;
-
- if (IDENT_TOKEN != get_token (ctok))
- {
- _SLparse_error ("Expecting name-space identifier", ctok, 0);
- return;
- }
-
- last_token = get_last_token ();
- if (-1 == combine_namespace_tokens (last_token, ctok))
- return;
-
- (void) get_token (ctok);
-}
-
-static int get_identifier_expr_token (_SLang_Token_Type *ctok)
-{
- _SLang_Token_Type next_token;
-
- if (IDENT_TOKEN != get_identifier_token (ctok))
- return -1;
-
- init_token (&next_token);
- if (NAMESPACE_TOKEN != get_token (&next_token))
- {
- unget_token (&next_token);
- return IDENT_TOKEN;
- }
-
- if (IDENT_TOKEN != get_identifier_token (&next_token))
- {
- free_token (&next_token);
- return -1;
- }
-
- if (-1 == combine_namespace_tokens (ctok, &next_token))
- {
- free_token (&next_token);
- return -1;
- }
- free_token (&next_token);
- return IDENT_TOKEN;
-}
-
-/* postfix-expression:
- * primary-expression
- * postfix-expression [ expression ]
- * postfix-expression ( function-args-expression )
- * postfix-expression . identifier
- * postfix-expression ^ unary-expression
- * postfix-expression ++
- * postfix-expression --
- * postfix-expression = simple-expression
- * postfix-expression += simple-expression
- * postfix-expression -= simple-expression
- *
- * primary-expression:
- * literal
- * identifier-expr
- * ( expression_opt )
- * [ inline-array-expression ]
- * &identifier-expr
- * struct-definition
- * __tmp(identifier-expr)
- *
- * identifier-expr:
- * identifier
- * identifier->identifier
- */
-static void postfix_expression (_SLang_Token_Type *ctok)
-{
- unsigned int start_pos, end_pos;
- unsigned char type;
-
- if (Token_List == NULL)
- return;
-
- start_pos = Token_List->len;
-
- switch (ctok->type)
- {
- case IDENT_TOKEN:
- append_identifier_token (ctok);
- break;
-
- case CHAR_TOKEN:
- case SHORT_TOKEN:
- case INT_TOKEN:
- case LONG_TOKEN:
- case UCHAR_TOKEN:
- case USHORT_TOKEN:
- case UINT_TOKEN:
- case ULONG_TOKEN:
- case STRING_TOKEN:
- case BSTRING_TOKEN:
-#ifdef SLANG_HAS_FLOAT
- case DOUBLE_TOKEN:
- case FLOAT_TOKEN:
-#endif
-#ifdef SLANG_HAS_COMPLEX
- case COMPLEX_TOKEN:
-#endif
- append_token (ctok);
- get_token (ctok);
- break;
-
- case OPAREN_TOKEN:
- if (CPAREN_TOKEN != get_token (ctok))
- {
- expression (ctok);
- if (ctok->type != CPAREN_TOKEN)
- _SLparse_error("Expecting )", ctok, 0);
- }
- get_token (ctok);
- break;
-
- case BAND_TOKEN:
- if (IDENT_TOKEN != get_identifier_expr_token (ctok))
- break;
-
- ctok->type = _REF_TOKEN;
- append_token (ctok);
- get_token (ctok);
- break;
-
- case OBRACKET_TOKEN:
- get_token (ctok);
- inline_array_expression (ctok);
- break;
-
- case NO_OP_LITERAL:
- /* This token was introduced by try_multiple_assignment. There,
- * a new token_list was pushed and (expression) was evaluated.
- * NO_OP_LITERAL represents the result of expression. However,
- * we need to tweak the start_pos variable to point to the beginning
- * of the token list to complete the equivalence.
- */
- start_pos = 0;
- get_token (ctok);
- break;
-
- case STRUCT_TOKEN:
- get_token (ctok);
- struct_declaration (ctok);
- break;
-
- case TMP_TOKEN:
- get_token (ctok);
- if (ctok->type == OPAREN_TOKEN)
- {
- if (IDENT_TOKEN == get_identifier_expr_token (ctok))
- {
- ctok->type = TMP_TOKEN;
- append_token (ctok);
- get_token (ctok);
- if (ctok->type == CPAREN_TOKEN)
- {
- get_token (ctok);
- break;
- }
- }
- }
- _SLparse_error ("Expecting form __tmp(NAME)", ctok, 0);
- break;
-
- default:
- if (IS_INTERNAL_FUNC(ctok->type))
- {
- append_token (ctok);
- get_token (ctok);
- }
- else
- _SLparse_error("Expecting a PRIMARY", ctok, 0);
- }
-
- while (SLang_Error == 0)
- {
- end_pos = Token_List->len;
- type = ctok->type;
- switch (type)
- {
- case OBRACKET_TOKEN: /* X[args] ==> [args] X ARRAY */
- get_token (ctok);
- append_token_of_type (ARG_TOKEN);
- if (ctok->type != CBRACKET_TOKEN)
- array_index_expression (ctok);
-
- if (ctok->type != CBRACKET_TOKEN)
- {
- _SLparse_error ("Expecting ']'", ctok, 0);
- return;
- }
- get_token (ctok);
- /* append_token_of_type (EARG_TOKEN); -- ARRAY_TOKEN implicitely does this */
- token_list_element_exchange (start_pos, end_pos);
- append_token_of_type (ARRAY_TOKEN);
- break;
-
- case OPAREN_TOKEN:
- /* f(args) ==> args f */
- if (CPAREN_TOKEN != get_token (ctok))
- {
- function_args_expression (ctok, 1);
- token_list_element_exchange (start_pos, end_pos);
- }
- else get_token (ctok);
- break;
-
- case DOT_TOKEN:
- /* S.a ==> "a" S DOT
- * This means that if S is X[b], then X[b].a ==> a b X ARRAY DOT
- * and f(a).X[b].c ==> "c" b "X" a f . ARRAY .
- * Also, f(a).X[b] = g(x); ==> x g b "X" a f .
- */
- if (IDENT_TOKEN != get_identifier_token (ctok))
- return;
-
- ctok->type = DOT_TOKEN;
- append_token (ctok);
- get_token (ctok);
- break;
-
- case PLUSPLUS_TOKEN:
- case MINUSMINUS_TOKEN:
- check_for_lvalue (type, NULL);
- get_token (ctok);
- break;
-
- case ASSIGN_TOKEN:
- case PLUSEQS_TOKEN:
- case MINUSEQS_TOKEN:
- case TIMESEQS_TOKEN:
- case DIVEQS_TOKEN:
- case BOREQS_TOKEN:
- case BANDEQS_TOKEN:
- check_for_lvalue (type, NULL);
- get_token (ctok);
- simple_expression (ctok);
- token_list_element_exchange (start_pos, end_pos);
- break;
-
- case POW_TOKEN:
- get_token (ctok);
- unary_expression (ctok);
- append_token_of_type (POW_TOKEN);
- break;
-
- default:
- return;
- }
- }
-}
-
-static void function_args_expression (_SLang_Token_Type *ctok, int handle_num_args)
-{
- unsigned char last_type, this_type;
-
- if (handle_num_args) append_token_of_type (ARG_TOKEN);
-
- last_type = COMMA_TOKEN;
-
- while (SLang_Error == 0)
- {
- this_type = ctok->type;
-
- switch (this_type)
- {
- case COMMA_TOKEN:
- if (last_type == COMMA_TOKEN)
- append_token_of_type (_NULL_TOKEN);
- get_token (ctok);
- break;
-
- case CPAREN_TOKEN:
- if (last_type == COMMA_TOKEN)
- append_token_of_type (_NULL_TOKEN);
- if (handle_num_args) append_token_of_type (EARG_TOKEN);
- get_token (ctok);
- return;
-
- default:
- simple_expression (ctok);
- if ((ctok->type != COMMA_TOKEN)
- && (ctok->type != CPAREN_TOKEN))
- {
- _SLparse_error ("Expecting ')'", ctok, 0);
- break;
- }
- }
- last_type = this_type;
- }
-}
-
-static int check_for_lvalue (unsigned char eqs_type, _SLang_Token_Type *ctok)
-{
- unsigned char type;
-
- if ((ctok == NULL)
- && (NULL == (ctok = get_last_token ())))
- return -1;
-
- type = ctok->type;
-
- eqs_type -= ASSIGN_TOKEN;
-
- if (type == IDENT_TOKEN)
- eqs_type += _SCALAR_ASSIGN_TOKEN;
- else if (type == ARRAY_TOKEN)
- eqs_type += _ARRAY_ASSIGN_TOKEN;
- else if (type == DOT_TOKEN)
- eqs_type += _STRUCT_ASSIGN_TOKEN;
- else
- {
- _SLparse_error ("Expecting LVALUE", ctok, 0);
- return -1;
- }
-
- ctok->type = eqs_type;
- return 0;
-}
-
-static void array_index_expression (_SLang_Token_Type *ctok)
-{
- unsigned int num_commas;
-
- num_commas = 0;
- while (1)
- {
- switch (ctok->type)
- {
- case COLON_TOKEN:
- if (num_commas)
- _SLparse_error ("Misplaced ':'", ctok, 0);
- return;
-
- case TIMES_TOKEN:
- append_token_of_type (_INLINE_WILDCARD_ARRAY_TOKEN);
- get_token (ctok);
- break;
-
- case COMMA_TOKEN:
- _SLparse_error ("Misplaced ','", ctok, 0);
- return;
-
- default:
- simple_expression (ctok);
- }
-
- if (ctok->type != COMMA_TOKEN)
- return;
- num_commas++;
- get_token (ctok);
- }
-}
-
-/* inline-array-expression:
- * array_index_expression
- * simple_expression : simple_expression
- * simple_expression : simple_expression : simple_expression
- */
-static void inline_array_expression (_SLang_Token_Type *ctok)
-{
- int num_colons = 0;
-
- append_token_of_type (ARG_TOKEN);
-
- if (ctok->type == COLON_TOKEN) /* [:...] */
- append_token_of_type (_NULL_TOKEN);
- else if (ctok->type != CBRACKET_TOKEN)
- array_index_expression (ctok);
-
- if (ctok->type == COLON_TOKEN)
- {
- num_colons++;
- if ((COLON_TOKEN == get_token (ctok))
- || (ctok->type == CBRACKET_TOKEN))
- append_token_of_type (_NULL_TOKEN);
- else
- simple_expression (ctok);
-
- if (ctok->type == COLON_TOKEN)
- {
- num_colons++;
- get_token (ctok);
- simple_expression (ctok);
- }
- }
-
- if (ctok->type != CBRACKET_TOKEN)
- {
- _SLparse_error ("Expecting ']'", ctok, 0);
- return;
- }
-
- /* append_token_of_type (EARG_TOKEN); */
- if (num_colons)
- append_token_of_type (_INLINE_IMPLICIT_ARRAY_TOKEN);
- else
- append_token_of_type (_INLINE_ARRAY_TOKEN);
- get_token (ctok);
-}
-
-static void do_multiple_assignment (_SLang_Token_Type *ctok)
-{
- _SLang_Token_Type *s;
- unsigned int i, k, len;
- unsigned char assign_type;
-
- assign_type = ctok->type;
-
- /* The LHS token list has already been pushed. Here we do the RHS
- * so push to another token list, process it, then come back to
- * LHS for assignment.
- */
- if (NULL == push_token_list ())
- return;
-
- get_token (ctok);
- expression (ctok);
- compile_token_list ();
-
- if (SLang_Error)
- return;
-
- /* Finally compile the LHS of the assignment expression
- * that has been saved.
- */
- s = Token_List->stack;
- len = Token_List->len;
-
- if (len == 0)
- {
- compile_token_of_type (POP_TOKEN);
- return;
- }
-
- while (len > 0)
- {
- /* List is of form:
- * a , b, c d e, f , g , , , h ,
- * The missing expressions will be replaced by a POP
- * ,,a
- */
-
- /* Start from back looking for a COMMA */
- k = len - 1;
- if (s[k].type == COMMA_TOKEN)
- {
- compile_token_of_type (POP_TOKEN);
- len = k;
- continue;
- }
-
- if (-1 == check_for_lvalue (assign_type, s + k))
- return;
-
- i = 0;
- while (1)
- {
- if (s[k].type == COMMA_TOKEN)
- {
- i = k + 1;
- break;
- }
-
- if (k == 0)
- break;
-
- k--;
- }
-
- while (i < len)
- {
- compile_token (s + i);
- i++;
- }
-
- len = k;
- }
-
- if (s[0].type == COMMA_TOKEN)
- compile_token_of_type (POP_TOKEN);
-}
-