Compare commits
No commits in common. "dc7aee91ce668ce4966d5c7794cea2e43be501e7" and "f4b2d113f73d3b299be35b96224a57b516dc7fd4" have entirely different histories.
dc7aee91ce
...
f4b2d113f7
8
Makefile
8
Makefile
@ -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) $<
|
||||||
|
@ -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,15 +5,17 @@
|
|||||||
#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';
|
||||||
@ -27,21 +28,21 @@ char lommereimar_fileiter_next(LommereimarFileIter* file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -50,106 +51,93 @@ void lommereimar_lexer_step(LommereimarLexer* lexer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
LommereimarExpr* lommereimar_parser_parse_term(LommereimarParser* parser)
|
|
||||||
{
|
{
|
||||||
// Grammar
|
// Grammar
|
||||||
// term -> factor (("+"|"-") factor):*
|
// term -> factor (("+"|"-") factor):*
|
||||||
LommereimarPosition pos = parser->current.pos;
|
Position pos = parser->current.pos;
|
||||||
LommereimarExpr* left = lommereimar_parser_parse_factor(parser);
|
Expr* left = parser_parse_factor(parser);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (parser->current.type == LommereimarTokenTypePlus) {
|
if (parser->current.type == TokenTypePlus) {
|
||||||
parser_step(parser);
|
parser_step(parser);
|
||||||
LommereimarExpr* right = lommereimar_parser_parse_factor(parser);
|
Expr* right = parser_parse_factor(parser);
|
||||||
left = allocate_expr((LommereimarExpr) {
|
left = allocate_expr((Expr) {
|
||||||
.type = LommereimarExprTypeBinary,
|
.type = ExprTypeBinary,
|
||||||
.pos = pos,
|
.pos = pos,
|
||||||
.binary = (LommereimarExprBinary) {
|
.binary = (ExprBinary) {
|
||||||
.type = LommereimarExprBinaryTypeAdd,
|
.type = ExprBinaryTypeAdd,
|
||||||
.left = left,
|
.left = left,
|
||||||
.right = right,
|
.right = right,
|
||||||
},
|
},
|
||||||
@ -158,4 +146,4 @@ LommereimarExpr* lommereimar_parser_parse_term(LommereimarParser* parser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) { return EXIT_SUCCESS; }
|
int main() { return EXIT_SUCCESS; }
|
||||||
|
@ -1,113 +1,115 @@
|
|||||||
#ifndef CALCULATOR_H
|
#ifndef CALCULATOR_H
|
||||||
#define CALCULATOR_H
|
#define CALCULATOR_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FILE* file;
|
FILE* file;
|
||||||
bool done;
|
bool done;
|
||||||
} LommereimarFileIter;
|
} FileIter;
|
||||||
|
|
||||||
LommereimarFileIter lommereimar_fileiter(const char* filename);
|
FileIter fileiter(const char* filename);
|
||||||
|
|
||||||
char lommereimar_fileiter_next(LommereimarFileIter* file);
|
char fileiter_next(FileIter* file);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int line;
|
int line;
|
||||||
int col;
|
int col;
|
||||||
} LommereimarPosition;
|
} Position;
|
||||||
|
|
||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user