From 040caee7f4da26069a85ea057cc5f2a3fb70d968 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 29 Mar 2019 16:01:59 +0100 Subject: [PATCH] as/lexer.c: move hex/dec parse functions to as/lexer/number.c --- Makefile | 3 +- as/lexer.c | 62 +++----------------------------------- as/lexer/number.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ as/lexer/number.h | 29 ++++++++++++++++++ 4 files changed, 112 insertions(+), 59 deletions(-) create mode 100644 as/lexer/number.c create mode 100644 as/lexer/number.h diff --git a/Makefile b/Makefile index 1d7261d..c5e77a3 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ m16vm : vm/vm.o vm/cpu.o vm/mm.o vm/instr_decode.o \ vm/syscall.o vm/program.o vm/debug.o lib/libm16.a $(QUIET_LD)$(LD) $(LDFLAGS) -o $@ $^ -m16as : as/as.o as/parser.o as/lexer.o \ +m16as : as/as.o as/parser.o as/lexer.o as/lexer/number.o \ as/codegen.o as/symtab.o \ as/ast.o lib/libm16.a $(QUIET_LD)$(LD) $(LDFLAGS) -o $@ $^ @@ -42,6 +42,7 @@ lib/libm16.a : lib/vector.o lib/error.o clean : $(RM) as/*.o + $(RM) as/lexer/*.o $(RM) vm/*.o $(RM) lib/*.o $(RM) lib/*.a diff --git a/as/lexer.c b/as/lexer.c index 29a3847..51d95c9 100644 --- a/as/lexer.c +++ b/as/lexer.c @@ -21,6 +21,7 @@ #include #include "asm_error.h" #include "lexer/grammar.h" +#include "lexer/number.h" #include "lexer.h" struct opcode_ent { @@ -67,62 +68,6 @@ static int read_next(struct lexer *lex) { return c; } -static int read_hex(FILE *fp, int *out) { - - int c, val = 0; - - while((c = fgetc(fp)) != EOF) { - char n = 0; - if (lexer_is_num(c)) { - n = c - '0'; - } - else if ( (c >= 'a' && c <= 'f') - || (c >= 'A' && c <= 'F')) { - n = (c % 0x20) + 9; - } - else { - ungetc(c, fp); - break; - } - - val = (val * 16) + n; - if (val > 0xFF) - goto overflow; - } - *out = val; - return 0; - -overflow: - *out = 0xFF; - return -1; -} - -static int read_dec(FILE *fp, int neg, int *out) { - - int c, val = 0; - - while((c = fgetc(fp)) != EOF) { - if (!lexer_is_num(c)) { - ungetc(c, fp); - break; - } - val = (val * 10) + (c - '0'); - - // Cool trick here. - // because the range is -128 (0x80) to +127 (0x7F) - // We can do 0x80 - 1 if it is NOT a negative number. - if (val > (0x80 - !neg)) - goto overflow; - } - - *out = neg ? -1 * val : val; - return 0; - -overflow: - *out = neg ? -1 * 0x80 : 0x7F; - return -1; -} - static int read_number(FILE *fp, int *out) { int neg = 0, c = fgetc(fp); @@ -132,7 +77,7 @@ static int read_number(FILE *fp, int *out) { c = fgetc(fp); if (c == 'x') { // We have a hexadecimal number. - return read_hex(fp, out); + return lexer_read_num_hex(fp, out); } ungetc(c, fp); ungetc('0', fp); @@ -146,7 +91,8 @@ static int read_number(FILE *fp, int *out) { ungetc(c, fp); } - return read_dec(fp, neg, out); + // Must be a decimal number. + return lexer_read_num_dec(fp, neg, out); } static int parse_number(struct lexer *lex) { diff --git a/as/lexer/number.c b/as/lexer/number.c new file mode 100644 index 0000000..b01e9eb --- /dev/null +++ b/as/lexer/number.c @@ -0,0 +1,77 @@ +/* lexer/number.c + * + * Copyright (C) 2018-2019 Henrik Hautakoski + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "grammar.h" +#include "number.h" + +int lexer_read_num_hex(FILE *fp, int *out) { + + int c, val = 0; + + while((c = fgetc(fp)) != EOF) { + char n = 0; + if (lexer_is_num(c)) { + n = c - '0'; + } + else if ( (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F')) { + n = (c % 0x20) + 9; + } + else { + ungetc(c, fp); + break; + } + + val = (val * 16) + n; + if (val > 0xFF) + goto overflow; + } + *out = val; + return 0; + +overflow: + *out = 0xFF; + return -1; +} + +int lexer_read_num_dec(FILE *fp, int neg, int *out) { + + int c, val = 0; + + while((c = fgetc(fp)) != EOF) { + if (!lexer_is_num(c)) { + ungetc(c, fp); + break; + } + val = (val * 10) + (c - '0'); + + // Cool trick here. + // because the range is -128 (0x80) to +127 (0x7F) + // We can do 0x80 - 1 if it is NOT a negative number. + if (val > (0x80 - !neg)) + goto overflow; + } + + *out = neg ? -1 * val : val; + return 0; + +overflow: + *out = neg ? -1 * 0x80 : 0x7F; + return -1; +} diff --git a/as/lexer/number.h b/as/lexer/number.h new file mode 100644 index 0000000..77404d2 --- /dev/null +++ b/as/lexer/number.h @@ -0,0 +1,29 @@ +/* lexer/number.h + * + * Copyright (C) 2018-2019 Henrik Hautakoski + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#ifndef ASM_LEXER_NUMBER_H +#define ASM_LEXER_NUMBER_H + +#include + +int lexer_read_num_hex(FILE *fp, int *out); + +int lexer_read_num_dec(FILE *fp, int neg, int *out); + +#endif /* ASM_LEXER_NUMBER_H */