mirror of
https://github.com/pnx/m16vm
synced 2026-06-16 03:44:55 +02:00
as/lexer.c: move hex/dec parse functions to as/lexer/number.c
This commit is contained in:
parent
caed36a936
commit
040caee7f4
4 changed files with 112 additions and 59 deletions
3
Makefile
3
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
|
||||
|
|
|
|||
62
as/lexer.c
62
as/lexer.c
|
|
@ -21,6 +21,7 @@
|
|||
#include <string.h>
|
||||
#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) {
|
||||
|
|
|
|||
77
as/lexer/number.c
Normal file
77
as/lexer/number.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/* lexer/number.c
|
||||
*
|
||||
* Copyright (C) 2018-2019 Henrik Hautakoski <henrik.hautakoski@gmail.com>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
29
as/lexer/number.h
Normal file
29
as/lexer/number.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* lexer/number.h
|
||||
*
|
||||
* Copyright (C) 2018-2019 Henrik Hautakoski <henrik.hautakoski@gmail.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
|
||||
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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue