X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Fsyntax.c;h=f99de050b87089721355ca52cd7e597df316f608;hb=8e63120c630c94c598d4e2d6ba823dac59bce8fa;hp=2486decb8969cd421de2bed9c24c74b5d376e72f;hpb=81ffe9a7de1db0b3a318a053b38882d1b7ab304c;p=inform.git diff --git a/src/syntax.c b/src/syntax.c index 2486dec..f99de05 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -1,9 +1,8 @@ /* ------------------------------------------------------------------------- */ /* "syntax" : Syntax analyser and compiler */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ -/* */ -/* This file is part of Inform. */ +/* Part of Inform 6.40 */ +/* copyright (c) Graham Nelson 1993 - 2022 */ /* */ /* Inform is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -85,13 +84,7 @@ extern void get_next_token_with_directives(void) This is called while parsing a long construct, such as Class or Object, where we want to support internal #ifdefs. (Although - function-parsing predates this and doesn't make use of it.) - - (Technically this permits *any* #-directive, which means you - can define global variables or properties or what-have-you in - the middle of an object. You can do that in the middle of an - object, too. Don't. It's about as well-supported as Wile E. - Coyote one beat before the plummet-lines kick in.) */ + function-parsing predates this and doesn't make use of it.) */ int directives_save, segment_markers_save, statements_save; @@ -153,9 +146,11 @@ extern void parse_program(char *source) extern int parse_directive(int internal_flag) { - /* Internal_flag is FALSE if the directive is encountered normally, - TRUE if encountered with a # prefix inside a routine or object - definition. + /* Internal_flag is FALSE if the directive is encountered normally + (at the top level of the program); TRUE if encountered with + a # prefix inside a routine or object definition. + + (Only directives like #ifdef are permitted inside a definition.) Returns: TRUE if program continues, FALSE if end of file reached. */ @@ -163,6 +158,11 @@ extern int parse_directive(int internal_flag) int is_renamed; begin_syntax_line(FALSE); + if (!internal_flag) { + /* An internal directive can occur in the middle of an expression or + object definition. So we only release for top-level directives. */ + release_token_texts(); + } get_next_token(); if (token_type == EOF_TT) return(FALSE); @@ -185,19 +185,22 @@ extern int parse_directive(int internal_flag) df_dont_note_global_symbols = TRUE; get_next_token(); df_dont_note_global_symbols = FALSE; - if ((token_type != SYMBOL_TT) - || ((!(sflags[token_value] & UNKNOWN_SFLAG)) - && (!(sflags[token_value] & REPLACE_SFLAG)))) + if (token_type != SYMBOL_TT) { ebf_error("routine name", token_text); return(FALSE); } + if ((!(symbols[token_value].flags & UNKNOWN_SFLAG)) + && (!(symbols[token_value].flags & REPLACE_SFLAG))) + { ebf_symbol_error("routine name", token_text, typename(symbols[token_value].type), symbols[token_value].line); + return(FALSE); + } routine_symbol = token_value; rep_symbol = routine_symbol; is_renamed = find_symbol_replacement(&rep_symbol); - if ((sflags[routine_symbol] & REPLACE_SFLAG) + if ((symbols[routine_symbol].flags & REPLACE_SFLAG) && !is_renamed && (is_systemfile())) { /* The function is definitely being replaced (system_file always loses priority in a replacement) but is not @@ -216,9 +219,9 @@ extern int parse_directive(int internal_flag) { /* Parse the function definition and assign its symbol. */ assign_symbol(routine_symbol, parse_routine(lexical_source, FALSE, - (char *) symbs[routine_symbol], FALSE, routine_symbol), + symbols[routine_symbol].name, FALSE, routine_symbol), ROUTINE_T); - slines[routine_symbol] = routine_starts_line; + symbols[routine_symbol].line = routine_starts_line; } if (is_renamed) { @@ -226,8 +229,8 @@ extern int parse_directive(int internal_flag) The first time we see a definition for symbol X, we copy it to Y -- that's the "original" form of the function. */ - if (svals[rep_symbol] == 0) { - assign_symbol(rep_symbol, svals[routine_symbol], ROUTINE_T); + if (symbols[rep_symbol].value == 0) { + assign_symbol(rep_symbol, symbols[routine_symbol].value, ROUTINE_T); } } @@ -239,13 +242,13 @@ extern int parse_directive(int internal_flag) return TRUE; } - if ((token_type == SYMBOL_TT) && (stypes[token_value] == CLASS_T)) + if ((token_type == SYMBOL_TT) && (symbols[token_value].type == CLASS_T)) { if (internal_flag) { error("It is illegal to nest an object in a routine using '#classname'"); return(TRUE); } - sflags[token_value] |= USED_SFLAG; - make_object(FALSE, NULL, -1, -1, svals[token_value]); + symbols[token_value].flags |= USED_SFLAG; + make_object(FALSE, NULL, -1, -1, symbols[token_value].value); return TRUE; } @@ -263,6 +266,7 @@ extern int parse_directive(int internal_flag) return !(parse_given_directive(internal_flag)); } +/* Check what's coming up after a switch case value. */ static int switch_sign(void) { if ((token_type == SEP_TT)&&(token_value == COLON_SEP)) return 1; @@ -271,8 +275,10 @@ static int switch_sign(void) return 0; } -static assembly_operand spec_stack[32]; -static int spec_type[32]; +/* Info for the current switch statement. Both arrays indexed by spec_sp */ +#define MAX_SPEC_STACK (32) +static assembly_operand spec_stack[MAX_SPEC_STACK]; +static int spec_type[MAX_SPEC_STACK]; static void compile_alternatives_z(assembly_operand switch_value, int n, int stack_level, int label, int flag) @@ -326,7 +332,7 @@ static void parse_switch_spec(assembly_operand switch_value, int label, sequence_point_follows = FALSE; do - { if (spec_sp == 32) + { if (spec_sp >= MAX_SPEC_STACK) { error("At most 32 values can be given in a single 'switch' case"); panic_mode_error_recovery(); return; @@ -446,7 +452,8 @@ extern int32 parse_routine(char *source, int embedded_flag, char *name, no_locals = 0; - for (i=0;i