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
|
CC = clang
|
||||||
LINK = clang
|
LINK = clang
|
||||||
CFLAGS = -Wall -DDBG -ggdb
|
CFLAGS = -Wall -DDBG -ggdb
|
||||||
LDFLAGS =
|
LDFLAGS = -lm
|
||||||
|
|
||||||
SRC_FILES = $(wildcard $(SRC_DIR)/*.c)
|
SRC_FILES = $(wildcard $(SRC_DIR)/*.c)
|
||||||
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))
|
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))
|
||||||
|
@ -35,13 +35,13 @@ input:
|
|||||||
;
|
;
|
||||||
|
|
||||||
exp:
|
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 {
|
| NUM PLUS NUM {
|
||||||
AST* argv[2] = {
|
AST* argv[2] = {
|
||||||
ast_init(AST_TYPE_NUM, ast_type_num_init($1)),
|
ast_init(AST_TYPE_NUM, ast_num_data_init($1)),
|
||||||
ast_init(AST_TYPE_NUM, ast_type_num_init($3))
|
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 YYSTYPE yylval;
|
||||||
extern char* inp;
|
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.)
|
// Called by `yyparse()` (in bison-generated files.)
|
||||||
int yylex();
|
int yylex();
|
||||||
void yyerror(char const* s);
|
void yyerror(char const* s);
|
||||||
|
43
src/lexer.c
43
src/lexer.c
@ -1,9 +1,45 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "include/lexer.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() {
|
int yylex() {
|
||||||
if (*inp == '\0') return YYEOF;
|
if (*inp == '\0') return YYEOF;
|
||||||
|
|
||||||
@ -15,12 +51,7 @@ int yylex() {
|
|||||||
|
|
||||||
// Check for NUM.
|
// Check for NUM.
|
||||||
if (isdigit(c)) {
|
if (isdigit(c)) {
|
||||||
int value = c - '0';
|
yylval.fval = acc_float(c); // Set the token value.
|
||||||
while (isdigit(*inp)) {
|
|
||||||
value = value * 10 + (*inp - '0'); // Accumulate value.
|
|
||||||
inp++;
|
|
||||||
}
|
|
||||||
yylval.fval = value; // Set the token value.
|
|
||||||
return NUM;
|
return NUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user