diff options
Diffstat (limited to 'mixlib/mix_scanner.l')
-rw-r--r-- | mixlib/mix_scanner.l | 104 |
1 files changed, 56 insertions, 48 deletions
diff --git a/mixlib/mix_scanner.l b/mixlib/mix_scanner.l index 8c6a186..6e4cb71 100644 --- a/mixlib/mix_scanner.l +++ b/mixlib/mix_scanner.l @@ -1,25 +1,26 @@ /* -*-c-*- -------------- mix_scanner.l : * Lexical scanner used by mix_parser_t * ------------------------------------------------------------------ - * Copyright (C) 2000 Free Software Foundation, Inc. - * + * Copyright (C) 2000, 2003 Free Software Foundation, Inc. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * + * */ %{ +#include <ctype.h> #include <string.h> #include "mix.h" @@ -104,13 +105,25 @@ BEGIN (INITIAL); \ } while (FALSE) - + static mix_word_t - eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y); - +eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y); + +static void yyunput(int, char*); + static void - unput_word_ (mix_word_t word); - +unput_word_ (mix_word_t word) + { + gchar *value; + gint k; + value = g_strdup_printf ("%s%ld", + mix_word_is_negative (word)? "-":"+", + mix_word_magnitude (word)); + for (k = strlen (value) - 1; k >= 0; --k) + unput (value[k]); + g_free (value); + } + %} %option nomain @@ -148,7 +161,7 @@ atexpr {digit}+|{symbol}|\* expr [+-]?{atexpr}({binop}{1}{atexpr})* fpart \({expr}\) wexpr {expr}({fpart})?(,{expr}({fpart})?)* - + %% @@ -161,14 +174,14 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* gchar *symbol = NULL, *lsymbol = NULL; mix_address_t loc = MIX_SHORT_ZERO; guint lineno = 1; - mix_ins_fill_from_id (ins, mix_NOP); - ins.address = 0; - ins.index = 0; + mix_ins_fill_from_id (ins, mix_NOP); + ins.address = 0; + ins.index = 0; parser->err_line = 0; yyin = mix_file_to_FILE (parser->in_file); - + %} - + <*><<EOF>> { mix_parser_log_error (parser, MIX_PERR_UNEX_EOF, lineno, NULL, FALSE); @@ -182,11 +195,11 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* yyless (0); BEGIN (LOC); } - \n { + \n { ++lineno; - if ( end ) return parser->status; + if ( end ) return parser->status; } -} +} <LOC>{ {ws}+ BEGIN (OP); /* LOC field is empty */ @@ -209,7 +222,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* } symbol[1] = 'B'; /* this will be referred as nB afterwards */ BEGIN (OP); - } + } {flocsymbol}|{blocsymbol} RETURN_ERROR (MIX_PERR_UNEX_LOC, yytext); {symbol}/({ws}+EQU) { /* store symbol name for future definition */ symbol = g_strdup (yytext); @@ -253,10 +266,18 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* mix_parser_log_error (parser, MIX_PERR_LONG_ALF, lineno, NULL, TRUE); value = mix_bytes_to_word (bytes, 5); - + ADD_RAW (value); } - [A-Z0-9]+{ws}*/\n | + ALF{ws}+.*\n { + gchar* msg; + guint k = 4; + while ( isspace(yytext[k]) ) k++; + msg = g_strdup_printf("\"%5s\"", g_strchomp (yytext + k)); + mix_parser_log_error (parser, MIX_PERR_UNQUOTED_ALF, lineno, msg, FALSE); + g_free (msg); + } + [A-Z0-9]+{ws}*/\n | [A-Z0-9]+{ws}+ { mix_ins_id_t id = mix_get_id_from_string (g_strchomp (yytext)); if ( id == mix_INVALID_INS ) @@ -268,7 +289,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* BEGIN (ADDRESS); } {expr} RETURN_ERROR (MIX_PERR_INV_OP, yytext); - . RETURN_ERROR (MIX_PERR_INV_OP, yytext); + . RETURN_ERROR (MIX_PERR_INV_OP, yytext); } @@ -336,7 +357,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* [+-]?{number}[(,\n] { ins.address = mix_short_new (atol (yytext)); switch ( yytext[yyleng-1] ) { - case '(' : BEGIN (FSPEC); break; + case '(' : BEGIN (FSPEC); break; case ',' : BEGIN (INDEX); break; case '\n' : ADD_INS (); break; default: g_assert_not_reached (); @@ -363,7 +384,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* \n ADD_INS (); . RETURN_ERROR (MIX_PERR_INV_ADDRESS, yytext); } - + <INDEX>{ {number}[\n(\t ] { @@ -383,7 +404,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* {expr}/[\n(\t ] ENTER_EVAL (); \n { mix_parser_log_error (parser, MIX_PERR_INV_IDX, lineno++, NULL, FALSE); - RESET (); + RESET (); BEGIN (INITIAL); } . RETURN_ERROR (MIX_PERR_INV_IDX, yytext); @@ -392,13 +413,13 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* <FSPEC>{ {number}")"(({ws}+.*\n)|\n) { glong val = atol (yytext); - if ( val < 0 || val > MIX_BYTE_MAX ) + if ( val < 0 || val > MIX_BYTE_MAX ) RETURN_ERROR (MIX_PERR_INV_FSPEC, NULL); - if ( ins.opcode != mix_opMOVE + if ( ins.opcode != mix_opMOVE && ( ins.opcode < mix_opJBUS || ins.opcode > mix_opJXx ) && !mix_fspec_is_valid (mix_byte_new (val)) ) RETURN_ERROR (MIX_PERR_INV_FSPEC, NULL); - if ( nof ) + if ( nof ) mix_parser_log_error (parser, MIX_PERR_INV_FSPEC, lineno, _("ignored"), TRUE); else @@ -426,11 +447,11 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, lineno, s, FALSE); yy_pop_state (); } - expr_val = eval_binop_ (yytext, expr_val, + expr_val = eval_binop_ (yytext, expr_val, mix_symbol_table_value (parser->symbol_table, s)); } {binop}"*" { - expr_val = eval_binop_ (yytext, expr_val, + expr_val = eval_binop_ (yytext, expr_val, mix_short_to_word_fast (parser->loc_count)); } "*" unput_word_ (mix_short_to_word_fast (parser->loc_count)); @@ -457,13 +478,13 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* mix_parser_log_error (parser, MIX_PERR_MIS_PAREN, lineno, NULL, FALSE); yy_pop_state (); } - if ( val < 0 || val > MIX_BYTE_MAX + if ( val < 0 || val > MIX_BYTE_MAX || !mix_fspec_is_valid (mix_byte_new (val)) ) { mix_parser_log_error (parser, MIX_PERR_INV_FSPEC, lineno, NULL, FALSE); yy_pop_state (); } is_fp = FALSE; - wexpr_val = mix_word_store_field (mix_byte_new (val), wexpr_val_tmp, + wexpr_val = mix_word_store_field (mix_byte_new (val), wexpr_val_tmp, wexpr_val); } {number}/[,()\n\t ] wexpr_val = mix_word_new (atol (yytext)); @@ -489,8 +510,8 @@ eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y) mix_word_t result = MIX_WORD_ZERO; switch (op[0]) { - case '+': - result = mix_word_add (x,y); + case '+': + result = mix_word_add (x,y); break; case '-': result = mix_word_sub (x,y); @@ -518,16 +539,3 @@ eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y) return result; } - -static void -unput_word_ (mix_word_t word) -{ - gchar *value; - gint k; - value = g_strdup_printf ("%s%ld", - mix_word_is_negative (word)? "-":"+", - mix_word_magnitude (word)); - for (k = strlen (value) - 1; k >= 0; --k) - unput (value[k]); - g_free (value); -} |