alias exported symbols
This commit is contained in:
parent
f4b2d113f7
commit
9891638d1e
@ -1,3 +1,4 @@
|
||||
#include "calculator.h"
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@ -5,145 +6,156 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "calculator.h"
|
||||
|
||||
FileIter fileiter(const char* filename)
|
||||
LommereimarFileIter lommereimar_fileiter(const char* filename)
|
||||
{
|
||||
return (FileIter) {
|
||||
.file = fopen(filename, "r"),
|
||||
.done = false,
|
||||
};
|
||||
return (LommereimarFileIter) {
|
||||
.file = fopen(filename, "r"),
|
||||
.done = false,
|
||||
};
|
||||
}
|
||||
|
||||
char fileiter_next(FileIter* file)
|
||||
char lommereimar_fileiter_next(LommereimarFileIter* file)
|
||||
{
|
||||
if (file->done)
|
||||
return '\0';
|
||||
int c = fgetc(file->file);
|
||||
if (c == EOF) {
|
||||
file->done = true;
|
||||
return '\0';
|
||||
} else {
|
||||
return (char)c;
|
||||
}
|
||||
if (file->done)
|
||||
return '\0';
|
||||
int c = fgetc(file->file);
|
||||
if (c == EOF) {
|
||||
file->done = true;
|
||||
return '\0';
|
||||
} else {
|
||||
return (char)c;
|
||||
}
|
||||
}
|
||||
|
||||
Lexer lexer(FileIter input_file)
|
||||
LommereimarLexer lommereimar_lexer(LommereimarFileIter input_file)
|
||||
{
|
||||
return (Lexer) {
|
||||
return (LommereimarLexer) {
|
||||
.input_file = input_file,
|
||||
.current = fileiter_next(&input_file),
|
||||
.pos = (Position) {
|
||||
.current = lommereimar_fileiter_next(&input_file),
|
||||
.pos = (LommereimarPosition) {
|
||||
.line = 1,
|
||||
.col = 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
void lexer_step(Lexer* lexer)
|
||||
void lommereimar_lexer_step(LommereimarLexer* lexer)
|
||||
{
|
||||
lexer->current = fileiter_next(&lexer->input_file);
|
||||
if (lexer->current) {
|
||||
lexer->pos.line++;
|
||||
lexer->pos.col = 1;
|
||||
} else {
|
||||
lexer->pos.col++;
|
||||
}
|
||||
lexer->current = lommereimar_fileiter_next(&lexer->input_file);
|
||||
if (lexer->current) {
|
||||
lexer->pos.line++;
|
||||
lexer->pos.col = 1;
|
||||
} else {
|
||||
lexer->pos.col++;
|
||||
}
|
||||
}
|
||||
|
||||
Token lexer_single_token(Lexer* lexer, TokenType token_type)
|
||||
#define lexer_step lommereimar_lexer_step
|
||||
|
||||
LommereimarToken lommereimar_lexer_single_token(
|
||||
LommereimarLexer* lexer, LommereimarTokenType token_type
|
||||
)
|
||||
{
|
||||
Position pos = lexer->pos;
|
||||
lexer_step(lexer);
|
||||
return (Token) {
|
||||
.type = TokenTypePlus,
|
||||
.pos = pos,
|
||||
.value = NULL,
|
||||
};
|
||||
LommereimarPosition pos = lexer->pos;
|
||||
lommereimar_lexer_step(lexer);
|
||||
return (LommereimarToken) {
|
||||
.type = token_type,
|
||||
.pos = pos,
|
||||
.value = NULL,
|
||||
};
|
||||
}
|
||||
|
||||
Token lexer_next(Lexer* lexer)
|
||||
#define single_token lommereimar_lexer_single_token
|
||||
|
||||
LommereimarToken lommereimar_lexer_next(LommereimarLexer* lexer)
|
||||
{
|
||||
if (isspace(lexer->current)) {
|
||||
while (isspace(lexer->current))
|
||||
lexer_step(lexer);
|
||||
return lexer_next(lexer);
|
||||
} else if (isdigit(lexer->current)) {
|
||||
Position pos = lexer->pos;
|
||||
size_t i = 0;
|
||||
char value[1234] = { 0 };
|
||||
while (isdigit(lexer->current)) {
|
||||
value[i] = lexer->current;
|
||||
lexer_step(lexer);
|
||||
}
|
||||
char* allocated_value = malloc(sizeof(char) * strlen(value) + 1);
|
||||
strcpy(allocated_value, value);
|
||||
return (Token) {
|
||||
.type = TokenTypeInt,
|
||||
.pos = pos,
|
||||
.value = allocated_value,
|
||||
};
|
||||
} else {
|
||||
switch (lexer->current) {
|
||||
case '+':
|
||||
return lexer_single_token(lexer, TokenTypePlus);
|
||||
case '-':
|
||||
return lexer_single_token(lexer, TokenTypeMinus);
|
||||
case '*':
|
||||
return lexer_single_token(lexer, TokenTypeAsterisk);
|
||||
case '/':
|
||||
return lexer_single_token(lexer, TokenTypeSlash);
|
||||
case '^':
|
||||
return lexer_single_token(lexer, TokenTypeHat);
|
||||
default:
|
||||
return lexer_single_token(lexer, TokenTypeInvalidChar);
|
||||
}
|
||||
}
|
||||
if (isspace(lexer->current)) {
|
||||
while (isspace(lexer->current))
|
||||
lommereimar_lexer_step(lexer);
|
||||
return lommereimar_lexer_next(lexer);
|
||||
} else if (isdigit(lexer->current)) {
|
||||
LommereimarPosition pos = lexer->pos;
|
||||
size_t i = 0;
|
||||
char value[1234] = { 0 };
|
||||
while (isdigit(lexer->current)) {
|
||||
value[i] = lexer->current;
|
||||
lommereimar_lexer_step(lexer);
|
||||
}
|
||||
char* allocated_value = malloc(sizeof(char) * strlen(value) + 1);
|
||||
strcpy(allocated_value, value);
|
||||
return (LommereimarToken) {
|
||||
.type = LommereimarTokenTypeInt,
|
||||
.pos = pos,
|
||||
.value = allocated_value,
|
||||
};
|
||||
} else {
|
||||
switch (lexer->current) {
|
||||
case '+':
|
||||
return single_token(lexer, LommereimarTokenTypePlus);
|
||||
case '-':
|
||||
return single_token(lexer, LommereimarTokenTypeMinus);
|
||||
case '*':
|
||||
return single_token(lexer, LommereimarTokenTypeAsterisk);
|
||||
case '/':
|
||||
return single_token(lexer, LommereimarTokenTypeSlash);
|
||||
case '^':
|
||||
return single_token(lexer, LommereimarTokenTypeHat);
|
||||
default:
|
||||
return single_token(lexer, LommereimarTokenTypeInvalidChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expr* allocate_expr(Expr data)
|
||||
LommereimarExpr* lommereimar_allocate_expr(LommereimarExpr data)
|
||||
{
|
||||
Expr* expr = malloc(sizeof(Expr));
|
||||
*expr = data;
|
||||
return expr;
|
||||
LommereimarExpr* expr = malloc(sizeof(LommereimarExpr));
|
||||
*expr = data;
|
||||
return expr;
|
||||
}
|
||||
|
||||
Parser parser(Lexer lexer)
|
||||
#define allocate_expr lommereimar_allocate_expr
|
||||
|
||||
LommereimarParser lommereimar_parser(LommereimarLexer lexer)
|
||||
{
|
||||
return (Parser) {
|
||||
.lexer = lexer,
|
||||
.current = lexer_next(&lexer),
|
||||
};
|
||||
return (LommereimarParser) {
|
||||
.lexer = lexer,
|
||||
.current = lommereimar_lexer_next(&lexer),
|
||||
};
|
||||
}
|
||||
|
||||
void parser_step(Parser* parser)
|
||||
void lommereimar_parser_step(LommereimarParser* parser)
|
||||
{
|
||||
parser->current = lexer_next(&parser->lexer);
|
||||
parser->current = lommereimar_lexer_next(&parser->lexer);
|
||||
}
|
||||
|
||||
Expr* parser_parse_expr(Parser* parser) { return parser_parse_term(parser); }
|
||||
#define parser_step lommereimar_parser_step
|
||||
|
||||
Expr* parser_parse_term(Parser* parser)
|
||||
LommereimarExpr* lommereimar_parser_parse_expr(LommereimarParser* parser)
|
||||
{
|
||||
// Grammar
|
||||
// term -> factor (("+"|"-") factor):*
|
||||
Position pos = parser->current.pos;
|
||||
Expr* left = parser_parse_factor(parser);
|
||||
for (;;) {
|
||||
if (parser->current.type == TokenTypePlus) {
|
||||
parser_step(parser);
|
||||
Expr* right = parser_parse_factor(parser);
|
||||
left = allocate_expr((Expr) {
|
||||
.type = ExprTypeBinary,
|
||||
return lommereimar_parser_parse_term(parser);
|
||||
}
|
||||
|
||||
LommereimarExpr* lommereimar_parser_parse_term(LommereimarParser* parser)
|
||||
{
|
||||
// Grammar
|
||||
// term -> factor (("+"|"-") factor):*
|
||||
LommereimarPosition pos = parser->current.pos;
|
||||
LommereimarExpr* left = lommereimar_parser_parse_factor(parser);
|
||||
for (;;) {
|
||||
if (parser->current.type == LommereimarTokenTypePlus) {
|
||||
parser_step(parser);
|
||||
LommereimarExpr* right = lommereimar_parser_parse_factor(parser);
|
||||
left = allocate_expr((LommereimarExpr) {
|
||||
.type = LommereimarExprTypeBinary,
|
||||
.pos = pos,
|
||||
.binary = (ExprBinary) {
|
||||
.type = ExprBinaryTypeAdd,
|
||||
.binary = (LommereimarExprBinary) {
|
||||
.type = LommereimarExprBinaryTypeAdd,
|
||||
.left = left,
|
||||
.right = right,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() { return EXIT_SUCCESS; }
|
||||
int main(void) { return EXIT_SUCCESS; }
|
||||
|
@ -1,115 +1,113 @@
|
||||
#ifndef CALCULATOR_H
|
||||
#define CALCULATOR_H
|
||||
|
||||
typedef struct {
|
||||
FILE* file;
|
||||
bool done;
|
||||
} FileIter;
|
||||
|
||||
FileIter fileiter(const char* filename);
|
||||
|
||||
char fileiter_next(FileIter* file);
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
int col;
|
||||
} Position;
|
||||
FILE* file;
|
||||
bool done;
|
||||
} LommereimarFileIter;
|
||||
|
||||
LommereimarFileIter lommereimar_fileiter(const char* filename);
|
||||
|
||||
char lommereimar_fileiter_next(LommereimarFileIter* file);
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
int col;
|
||||
} LommereimarPosition;
|
||||
|
||||
typedef enum {
|
||||
TokenTypeEof,
|
||||
TokenTypeInvalidChar,
|
||||
TokenTypeInt,
|
||||
TokenTypePlus,
|
||||
TokenTypeMinus,
|
||||
TokenTypeAsterisk,
|
||||
TokenTypeSlash,
|
||||
TokenTypeHat,
|
||||
TokenTypeLParen,
|
||||
TokenTypeRParen,
|
||||
} TokenType;
|
||||
LommereimarTokenTypeEof,
|
||||
LommereimarTokenTypeInvalidChar,
|
||||
LommereimarTokenTypeInt,
|
||||
LommereimarTokenTypePlus,
|
||||
LommereimarTokenTypeMinus,
|
||||
LommereimarTokenTypeAsterisk,
|
||||
LommereimarTokenTypeSlash,
|
||||
LommereimarTokenTypeHat,
|
||||
LommereimarTokenTypeLParen,
|
||||
LommereimarTokenTypeRParen,
|
||||
} LommereimarTokenType;
|
||||
|
||||
typedef struct {
|
||||
// optional
|
||||
char* value;
|
||||
TokenType type;
|
||||
Position pos;
|
||||
} Token;
|
||||
// optional
|
||||
char* value;
|
||||
LommereimarTokenType type;
|
||||
LommereimarPosition pos;
|
||||
} LommereimarToken;
|
||||
|
||||
typedef struct {
|
||||
FileIter input_file;
|
||||
char current;
|
||||
Position pos;
|
||||
} Lexer;
|
||||
LommereimarFileIter input_file;
|
||||
char current;
|
||||
LommereimarPosition pos;
|
||||
} LommereimarLexer;
|
||||
|
||||
Lexer lexer(FileIter input_file);
|
||||
|
||||
void lexer_step(Lexer* lexer);
|
||||
|
||||
Token lexer_single_token(Lexer* lexer, TokenType token_type);
|
||||
|
||||
Token lexer_next(Lexer* lexer);
|
||||
LommereimarLexer lommereimar_lexer(LommereimarFileIter input_file);
|
||||
void lommereimar_lexer_step(LommereimarLexer* lexer);
|
||||
LommereimarToken lommereimar_lexer_single_token(
|
||||
LommereimarLexer* lexer, LommereimarTokenType token_type
|
||||
);
|
||||
LommereimarToken lommereimar_lexer_next(LommereimarLexer* lexer);
|
||||
|
||||
typedef enum {
|
||||
ExprTypeEof,
|
||||
ExprTypeError,
|
||||
ExprTypeInt,
|
||||
ExprTypeFloat,
|
||||
ExprTypeUnary,
|
||||
ExprTypeBinary,
|
||||
} ExprType;
|
||||
LommereimarExprTypeEof,
|
||||
LommereimarExprTypeError,
|
||||
LommereimarExprTypeInt,
|
||||
LommereimarExprTypeFloat,
|
||||
LommereimarExprTypeUnary,
|
||||
LommereimarExprTypeBinary,
|
||||
} LommereimarExprType;
|
||||
|
||||
typedef struct Expr Expr;
|
||||
typedef struct LommereimarExpr LommereimarExpr;
|
||||
|
||||
typedef enum {
|
||||
ExprBinaryTypeAdd,
|
||||
ExprBinaryTypeSubtract,
|
||||
ExprBinaryTypeMultiply,
|
||||
ExprBinaryTypeDivide,
|
||||
ExprBinaryTypeExponent,
|
||||
} ExprBinaryType;
|
||||
LommereimarExprBinaryTypeAdd,
|
||||
LommereimarExprBinaryTypeSubtract,
|
||||
LommereimarExprBinaryTypeMultiply,
|
||||
LommereimarExprBinaryTypeDivide,
|
||||
LommereimarExprBinaryTypeExponent,
|
||||
} LommereimarExprBinaryType;
|
||||
|
||||
typedef struct {
|
||||
ExprBinaryType type;
|
||||
Expr* left;
|
||||
Expr* right;
|
||||
} ExprBinary;
|
||||
LommereimarExprBinaryType type;
|
||||
LommereimarExpr* left;
|
||||
LommereimarExpr* right;
|
||||
} LommereimarExprBinary;
|
||||
|
||||
typedef enum {
|
||||
ExprUnaryTypeNegate,
|
||||
} ExprUnaryType;
|
||||
LommereimarExprUnaryTypeNegate,
|
||||
} LommereimarExprUnaryType;
|
||||
|
||||
typedef struct {
|
||||
ExprUnaryType type;
|
||||
Expr* subject;
|
||||
} ExprUnary;
|
||||
LommereimarExprUnaryType type;
|
||||
LommereimarExpr* subject;
|
||||
} LommereimarExprUnary;
|
||||
|
||||
struct Expr {
|
||||
ExprType type;
|
||||
Position pos;
|
||||
union {
|
||||
char* error_value;
|
||||
int int_value;
|
||||
float float_value;
|
||||
ExprUnary unary;
|
||||
ExprBinary binary;
|
||||
};
|
||||
struct LommereimarExpr {
|
||||
LommereimarExprType type;
|
||||
LommereimarPosition pos;
|
||||
union {
|
||||
char* error_value;
|
||||
int int_value;
|
||||
float float_value;
|
||||
LommereimarExprUnary unary;
|
||||
LommereimarExprBinary binary;
|
||||
};
|
||||
};
|
||||
|
||||
Expr* allocate_expr(Expr data);
|
||||
LommereimarExpr* lommereimar_allocate_expr(LommereimarExpr data);
|
||||
|
||||
typedef struct {
|
||||
Lexer lexer;
|
||||
Token current;
|
||||
} Parser;
|
||||
LommereimarLexer lexer;
|
||||
LommereimarToken current;
|
||||
} LommereimarParser;
|
||||
|
||||
Parser parser(Lexer lexer);
|
||||
|
||||
void parser_step(Parser* parser);
|
||||
|
||||
Expr* parser_parse_expr(Parser* parser);
|
||||
|
||||
Expr* parser_parse_term(Parser* parser);
|
||||
|
||||
Expr* parser_parse_factor(Parser* parser);
|
||||
LommereimarParser lommereimar_parser(LommereimarLexer lexer);
|
||||
void lommereimar_parser_step(LommereimarParser* parser);
|
||||
LommereimarExpr* lommereimar_parser_parse_expr(LommereimarParser* parser);
|
||||
LommereimarExpr* lommereimar_parser_parse_term(LommereimarParser* parser);
|
||||
LommereimarExpr* lommereimar_parser_parse_factor(LommereimarParser* parser);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user