Compare commits

..

No commits in common. "dc7aee91ce668ce4966d5c7794cea2e43be501e7" and "f4b2d113f73d3b299be35b96224a57b516dc7fd4" have entirely different histories.

3 changed files with 186 additions and 202 deletions

View File

@ -12,7 +12,7 @@ CFLAGS = \
# CFLAGS += -O3 # CFLAGS += -O3
CFLAGS += -g CFLAGS += -g
all: compile_flags.txt dirs scirpt lommereimar all: compile_flags.txt dirs scirpt
COMMON_SRC = string.c stringmap.c COMMON_SRC = string.c stringmap.c
COMMON_OBJ = $(patsubst %.c, build/common/%.o, $(COMMON_SRC)) COMMON_OBJ = $(patsubst %.c, build/common/%.o, $(COMMON_SRC))
@ -23,12 +23,6 @@ SCIRPT_OBJ = $(patsubst %.c, build/scirpt/%.o, $(SCIRPT_SRC))
scirpt: $(SCIRPT_OBJ) $(COMMON_OBJ) scirpt: $(SCIRPT_OBJ) $(COMMON_OBJ)
$(CC) -o bin/$@ $(CFLAGS) $^ -lm $(CC) -o bin/$@ $(CFLAGS) $^ -lm
LOMMEREIMAR_SRC = calculator.c
LOMMEREIMAR_OBJ = $(patsubst %.c, build/lommereimar/%.o, $(LOMMEREIMAR_SRC))
lommereimar: $(LOMMEREIMAR_OBJ) $(COMMON_OBJ)
$(CC) -o bin/$@ $(CFLAGS) $^ -lm
build/%.o: %.c $(shell find -name *.h) build/%.o: %.c $(shell find -name *.h)
mkdir $(@D) -p mkdir $(@D) -p
$(CC) -c -o $@ $(CFLAGS) $< $(CC) -c -o $@ $(CFLAGS) $<

View File

@ -1,4 +1,3 @@
#include "calculator.h"
#include <ctype.h> #include <ctype.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
@ -6,156 +5,145 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
LommereimarFileIter lommereimar_fileiter(const char* filename) #include "calculator.h"
FileIter fileiter(const char* filename)
{ {
return (LommereimarFileIter) { return (FileIter) {
.file = fopen(filename, "r"), .file = fopen(filename, "r"),
.done = false, .done = false,
}; };
} }
char lommereimar_fileiter_next(LommereimarFileIter* file) char fileiter_next(FileIter* file)
{ {
if (file->done) if (file->done)
return '\0'; return '\0';
int c = fgetc(file->file); int c = fgetc(file->file);
if (c == EOF) { if (c == EOF) {
file->done = true; file->done = true;
return '\0'; return '\0';
} else { } else {
return (char)c; return (char)c;
} }
} }
LommereimarLexer lommereimar_lexer(LommereimarFileIter input_file) Lexer lexer(FileIter input_file)
{ {
return (LommereimarLexer) { return (Lexer) {
.input_file = input_file, .input_file = input_file,
.current = lommereimar_fileiter_next(&input_file), .current = fileiter_next(&input_file),
.pos = (LommereimarPosition) { .pos = (Position) {
.line = 1, .line = 1,
.col = 1, .col = 1,
}, },
}; };
} }
void lommereimar_lexer_step(LommereimarLexer* lexer) void lexer_step(Lexer* lexer)
{ {
lexer->current = lommereimar_fileiter_next(&lexer->input_file); lexer->current = fileiter_next(&lexer->input_file);
if (lexer->current) { if (lexer->current) {
lexer->pos.line++; lexer->pos.line++;
lexer->pos.col = 1; lexer->pos.col = 1;
} else { } else {
lexer->pos.col++; lexer->pos.col++;
} }
} }
#define lexer_step lommereimar_lexer_step Token lexer_single_token(Lexer* lexer, TokenType token_type)
LommereimarToken lommereimar_lexer_single_token(
LommereimarLexer* lexer, LommereimarTokenType token_type
)
{ {
LommereimarPosition pos = lexer->pos; Position pos = lexer->pos;
lommereimar_lexer_step(lexer); lexer_step(lexer);
return (LommereimarToken) { return (Token) {
.type = token_type, .type = TokenTypePlus,
.pos = pos, .pos = pos,
.value = NULL, .value = NULL,
}; };
} }
#define single_token lommereimar_lexer_single_token Token lexer_next(Lexer* lexer)
LommereimarToken lommereimar_lexer_next(LommereimarLexer* lexer)
{ {
if (isspace(lexer->current)) { if (isspace(lexer->current)) {
while (isspace(lexer->current)) while (isspace(lexer->current))
lommereimar_lexer_step(lexer); lexer_step(lexer);
return lommereimar_lexer_next(lexer); return lexer_next(lexer);
} else if (isdigit(lexer->current)) { } else if (isdigit(lexer->current)) {
LommereimarPosition pos = lexer->pos; Position pos = lexer->pos;
size_t i = 0; size_t i = 0;
char value[1234] = { 0 }; char value[1234] = { 0 };
while (isdigit(lexer->current)) { while (isdigit(lexer->current)) {
value[i] = lexer->current; value[i] = lexer->current;
lommereimar_lexer_step(lexer); lexer_step(lexer);
} }
char* allocated_value = malloc(sizeof(char) * strlen(value) + 1); char* allocated_value = malloc(sizeof(char) * strlen(value) + 1);
strcpy(allocated_value, value); strcpy(allocated_value, value);
return (LommereimarToken) { return (Token) {
.type = LommereimarTokenTypeInt, .type = TokenTypeInt,
.pos = pos, .pos = pos,
.value = allocated_value, .value = allocated_value,
}; };
} else { } else {
switch (lexer->current) { switch (lexer->current) {
case '+': case '+':
return single_token(lexer, LommereimarTokenTypePlus); return lexer_single_token(lexer, TokenTypePlus);
case '-': case '-':
return single_token(lexer, LommereimarTokenTypeMinus); return lexer_single_token(lexer, TokenTypeMinus);
case '*': case '*':
return single_token(lexer, LommereimarTokenTypeAsterisk); return lexer_single_token(lexer, TokenTypeAsterisk);
case '/': case '/':
return single_token(lexer, LommereimarTokenTypeSlash); return lexer_single_token(lexer, TokenTypeSlash);
case '^': case '^':
return single_token(lexer, LommereimarTokenTypeHat); return lexer_single_token(lexer, TokenTypeHat);
default: default:
return single_token(lexer, LommereimarTokenTypeInvalidChar); return lexer_single_token(lexer, TokenTypeInvalidChar);
} }
} }
} }
LommereimarExpr* lommereimar_allocate_expr(LommereimarExpr data) Expr* allocate_expr(Expr data)
{ {
LommereimarExpr* expr = malloc(sizeof(LommereimarExpr)); Expr* expr = malloc(sizeof(Expr));
*expr = data; *expr = data;
return expr; return expr;
} }
#define allocate_expr lommereimar_allocate_expr Parser parser(Lexer lexer)
LommereimarParser lommereimar_parser(LommereimarLexer lexer)
{ {
return (LommereimarParser) { return (Parser) {
.lexer = lexer, .lexer = lexer,
.current = lommereimar_lexer_next(&lexer), .current = lexer_next(&lexer),
}; };
} }
void lommereimar_parser_step(LommereimarParser* parser) void parser_step(Parser* parser)
{ {
parser->current = lommereimar_lexer_next(&parser->lexer); parser->current = lexer_next(&parser->lexer);
} }
#define parser_step lommereimar_parser_step Expr* parser_parse_expr(Parser* parser) { return parser_parse_term(parser); }
LommereimarExpr* lommereimar_parser_parse_expr(LommereimarParser* parser) Expr* parser_parse_term(Parser* parser)
{ {
return lommereimar_parser_parse_term(parser); // Grammar
} // term -> factor (("+"|"-") factor):*
Position pos = parser->current.pos;
LommereimarExpr* lommereimar_parser_parse_term(LommereimarParser* parser) Expr* left = parser_parse_factor(parser);
{ for (;;) {
// Grammar if (parser->current.type == TokenTypePlus) {
// term -> factor (("+"|"-") factor):* parser_step(parser);
LommereimarPosition pos = parser->current.pos; Expr* right = parser_parse_factor(parser);
LommereimarExpr* left = lommereimar_parser_parse_factor(parser); left = allocate_expr((Expr) {
for (;;) { .type = ExprTypeBinary,
if (parser->current.type == LommereimarTokenTypePlus) {
parser_step(parser);
LommereimarExpr* right = lommereimar_parser_parse_factor(parser);
left = allocate_expr((LommereimarExpr) {
.type = LommereimarExprTypeBinary,
.pos = pos, .pos = pos,
.binary = (LommereimarExprBinary) { .binary = (ExprBinary) {
.type = LommereimarExprBinaryTypeAdd, .type = ExprBinaryTypeAdd,
.left = left, .left = left,
.right = right, .right = right,
}, },
}); });
} }
} }
} }
int main(void) { return EXIT_SUCCESS; } int main() { return EXIT_SUCCESS; }

View File

@ -1,113 +1,115 @@
#ifndef CALCULATOR_H #ifndef CALCULATOR_H
#define CALCULATOR_H #define CALCULATOR_H
#include <stdbool.h> typedef struct {
#include <stdio.h> FILE* file;
bool done;
} FileIter;
FileIter fileiter(const char* filename);
char fileiter_next(FileIter* file);
typedef struct { typedef struct {
FILE* file; int line;
bool done; int col;
} LommereimarFileIter; } Position;
LommereimarFileIter lommereimar_fileiter(const char* filename);
char lommereimar_fileiter_next(LommereimarFileIter* file);
typedef struct {
int line;
int col;
} LommereimarPosition;
typedef enum { typedef enum {
LommereimarTokenTypeEof, TokenTypeEof,
LommereimarTokenTypeInvalidChar, TokenTypeInvalidChar,
LommereimarTokenTypeInt, TokenTypeInt,
LommereimarTokenTypePlus, TokenTypePlus,
LommereimarTokenTypeMinus, TokenTypeMinus,
LommereimarTokenTypeAsterisk, TokenTypeAsterisk,
LommereimarTokenTypeSlash, TokenTypeSlash,
LommereimarTokenTypeHat, TokenTypeHat,
LommereimarTokenTypeLParen, TokenTypeLParen,
LommereimarTokenTypeRParen, TokenTypeRParen,
} LommereimarTokenType; } TokenType;
typedef struct { typedef struct {
// optional // optional
char* value; char* value;
LommereimarTokenType type; TokenType type;
LommereimarPosition pos; Position pos;
} LommereimarToken; } Token;
typedef struct { typedef struct {
LommereimarFileIter input_file; FileIter input_file;
char current; char current;
LommereimarPosition pos; Position pos;
} LommereimarLexer; } Lexer;
LommereimarLexer lommereimar_lexer(LommereimarFileIter input_file); Lexer lexer(FileIter input_file);
void lommereimar_lexer_step(LommereimarLexer* lexer);
LommereimarToken lommereimar_lexer_single_token( void lexer_step(Lexer* lexer);
LommereimarLexer* lexer, LommereimarTokenType token_type
); Token lexer_single_token(Lexer* lexer, TokenType token_type);
LommereimarToken lommereimar_lexer_next(LommereimarLexer* lexer);
Token lexer_next(Lexer* lexer);
typedef enum { typedef enum {
LommereimarExprTypeEof, ExprTypeEof,
LommereimarExprTypeError, ExprTypeError,
LommereimarExprTypeInt, ExprTypeInt,
LommereimarExprTypeFloat, ExprTypeFloat,
LommereimarExprTypeUnary, ExprTypeUnary,
LommereimarExprTypeBinary, ExprTypeBinary,
} LommereimarExprType; } ExprType;
typedef struct LommereimarExpr LommereimarExpr; typedef struct Expr Expr;
typedef enum { typedef enum {
LommereimarExprBinaryTypeAdd, ExprBinaryTypeAdd,
LommereimarExprBinaryTypeSubtract, ExprBinaryTypeSubtract,
LommereimarExprBinaryTypeMultiply, ExprBinaryTypeMultiply,
LommereimarExprBinaryTypeDivide, ExprBinaryTypeDivide,
LommereimarExprBinaryTypeExponent, ExprBinaryTypeExponent,
} LommereimarExprBinaryType; } ExprBinaryType;
typedef struct { typedef struct {
LommereimarExprBinaryType type; ExprBinaryType type;
LommereimarExpr* left; Expr* left;
LommereimarExpr* right; Expr* right;
} LommereimarExprBinary; } ExprBinary;
typedef enum { typedef enum {
LommereimarExprUnaryTypeNegate, ExprUnaryTypeNegate,
} LommereimarExprUnaryType; } ExprUnaryType;
typedef struct { typedef struct {
LommereimarExprUnaryType type; ExprUnaryType type;
LommereimarExpr* subject; Expr* subject;
} LommereimarExprUnary; } ExprUnary;
struct LommereimarExpr { struct Expr {
LommereimarExprType type; ExprType type;
LommereimarPosition pos; Position pos;
union { union {
char* error_value; char* error_value;
int int_value; int int_value;
float float_value; float float_value;
LommereimarExprUnary unary; ExprUnary unary;
LommereimarExprBinary binary; ExprBinary binary;
}; };
}; };
LommereimarExpr* lommereimar_allocate_expr(LommereimarExpr data); Expr* allocate_expr(Expr data);
typedef struct { typedef struct {
LommereimarLexer lexer; Lexer lexer;
LommereimarToken current; Token current;
} LommereimarParser; } Parser;
LommereimarParser lommereimar_parser(LommereimarLexer lexer); Parser parser(Lexer lexer);
void lommereimar_parser_step(LommereimarParser* parser);
LommereimarExpr* lommereimar_parser_parse_expr(LommereimarParser* parser); void parser_step(Parser* parser);
LommereimarExpr* lommereimar_parser_parse_term(LommereimarParser* parser);
LommereimarExpr* lommereimar_parser_parse_factor(LommereimarParser* parser); Expr* parser_parse_expr(Parser* parser);
Expr* parser_parse_term(Parser* parser);
Expr* parser_parse_factor(Parser* parser);
#endif #endif