Addition with floats is now entirely possible.
This commit is contained in:
parent
8e5b39a6e4
commit
85e17ede84
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ TEST_OBJ_DIR = $(TEST_BUILD_DIR)/obj
|
||||
CC = clang
|
||||
LINK = clang
|
||||
CFLAGS = -Wall -DDBG -ggdb
|
||||
LDFLAGS =
|
||||
LDFLAGS = -lm
|
||||
|
||||
SRC_FILES = $(wildcard $(SRC_DIR)/*.c)
|
||||
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))
|
||||
|
@ -35,13 +35,13 @@ input:
|
||||
;
|
||||
|
||||
exp:
|
||||
NUM { $$ = ast_init(AST_TYPE_NUM, ast_type_num_init($1)); }
|
||||
NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); }
|
||||
| NUM PLUS NUM {
|
||||
AST* argv[2] = {
|
||||
ast_init(AST_TYPE_NUM, ast_type_num_init($1)),
|
||||
ast_init(AST_TYPE_NUM, ast_type_num_init($3))
|
||||
ast_init(AST_TYPE_NUM, ast_num_data_init($1)),
|
||||
ast_init(AST_TYPE_NUM, ast_num_data_init($3))
|
||||
};
|
||||
$$ = ast_init(AST_TYPE_CALL, ast_type_call_init("+", 2, argv));
|
||||
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("+", 2, argv));
|
||||
};
|
||||
|
||||
%%
|
||||
|
@ -17,6 +17,12 @@
|
||||
extern YYSTYPE yylval;
|
||||
extern char* inp;
|
||||
|
||||
// Accumulate an integer.
|
||||
int acc_int(int c);
|
||||
|
||||
// Accumulate a floating-point number.
|
||||
double acc_float(int c);
|
||||
|
||||
// Called by `yyparse()` (in bison-generated files.)
|
||||
int yylex();
|
||||
void yyerror(char const* s);
|
||||
|
43
src/lexer.c
43
src/lexer.c
@ -1,9 +1,45 @@
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "include/lexer.h"
|
||||
|
||||
int acc_int(int c) {
|
||||
int value = c - '0';
|
||||
while (isdigit(*inp)) {
|
||||
value = value * 10 + (*inp - '0'); // Accumulate value.
|
||||
inp++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
double acc_float(int c) {
|
||||
double value = (double)(c - '0');
|
||||
|
||||
// Grab everything prior to '.'.
|
||||
while (isdigit(*inp)) {
|
||||
value = value * 10 + (*inp - '0'); // Accumulate value.
|
||||
inp++;
|
||||
}
|
||||
|
||||
if (*inp == '.') {
|
||||
char* oinp = inp++;
|
||||
while (isdigit(*inp)) {
|
||||
// Accumulate as int, divide once at end.
|
||||
value = value + (((double)(*inp - '0'))/pow(10.0l, (double)(inp-oinp))); // Accumulate value.
|
||||
inp++;
|
||||
}
|
||||
}
|
||||
|
||||
// > 1.20000
|
||||
// = 1.0 + 2/10
|
||||
|
||||
// > 1.23
|
||||
// = 1.2 + 3/100
|
||||
return value;
|
||||
}
|
||||
|
||||
int yylex() {
|
||||
if (*inp == '\0') return YYEOF;
|
||||
|
||||
@ -15,12 +51,7 @@ int yylex() {
|
||||
|
||||
// Check for NUM.
|
||||
if (isdigit(c)) {
|
||||
int value = c - '0';
|
||||
while (isdigit(*inp)) {
|
||||
value = value * 10 + (*inp - '0'); // Accumulate value.
|
||||
inp++;
|
||||
}
|
||||
yylval.fval = value; // Set the token value.
|
||||
yylval.fval = acc_float(c); // Set the token value.
|
||||
return NUM;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user