add runtime
This commit is contained in:
parent
2de85bf57d
commit
333f846768
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
|
||||
build/
|
||||
compile_flags.txt
|
||||
Session.vim
|
||||
|
||||
|
42
src/lexer.c
42
src/lexer.c
@ -50,6 +50,7 @@ void string_append_char(String* string, char value)
|
||||
}
|
||||
string->data[string->length] = value;
|
||||
string->length += 1;
|
||||
string->data[string->length] = '\0';
|
||||
}
|
||||
|
||||
void string_from_cstr(String* string, const char* value)
|
||||
@ -66,17 +67,6 @@ void string_from_slice(String* string, StringSlice slice)
|
||||
}
|
||||
}
|
||||
|
||||
void file_char_reader_construct(FileCharReader* reader, FILE* file)
|
||||
{
|
||||
*reader = (FileCharReader) {
|
||||
.next = file_char_reader_next,
|
||||
.value = file_char_reader_value,
|
||||
.file = file,
|
||||
.buffer = { 0 },
|
||||
};
|
||||
string_construct(&reader->buffer);
|
||||
}
|
||||
|
||||
void string_append_cstr(String* string, const char* value)
|
||||
{
|
||||
size_t value_length = strlen(value);
|
||||
@ -84,8 +74,6 @@ void string_append_cstr(String* string, const char* value)
|
||||
if (string->length + value_length + 1 > string->capacity) {
|
||||
if (string->capacity == 0) {
|
||||
string->capacity = string_starting_alloc_size;
|
||||
} else {
|
||||
string->capacity *= 2;
|
||||
}
|
||||
while (string->length + value_length + 1 > string->capacity) {
|
||||
string->capacity *= 2;
|
||||
@ -96,7 +84,9 @@ void string_append_cstr(String* string, const char* value)
|
||||
string->data = new_buffer;
|
||||
}
|
||||
|
||||
strncpy(&string->data[string->length], value, value_length);
|
||||
memcpy(&string->data[string->length], value, value_length);
|
||||
string->length += value_length;
|
||||
string->data[string->length] = '\0';
|
||||
}
|
||||
|
||||
void string_append_formatted(String* string, const char* format, ...)
|
||||
@ -106,6 +96,10 @@ void string_append_formatted(String* string, const char* format, ...)
|
||||
|
||||
size_t format_length = (size_t)vsnprintf(NULL, 0, format, varargs);
|
||||
|
||||
va_end(varargs);
|
||||
|
||||
va_start(varargs, format);
|
||||
|
||||
if (string->length + format_length + 1 > string->capacity) {
|
||||
if (string->capacity == 0) {
|
||||
string->capacity = string_starting_alloc_size;
|
||||
@ -127,8 +121,8 @@ void string_append_formatted(String* string, const char* format, ...)
|
||||
format,
|
||||
varargs
|
||||
);
|
||||
ASSERT(written == format_length);
|
||||
string->length += written;
|
||||
string->data[string->length] = '\0';
|
||||
|
||||
va_end(varargs);
|
||||
}
|
||||
@ -138,6 +132,17 @@ bool string_equal(const String* string, const char* value)
|
||||
return strncmp(value, string->data, string->length + 1);
|
||||
}
|
||||
|
||||
void file_char_reader_construct(FileCharReader* reader, FILE* file)
|
||||
{
|
||||
*reader = (FileCharReader) {
|
||||
.next = file_char_reader_next,
|
||||
.value = file_char_reader_value,
|
||||
.file = file,
|
||||
.buffer = { 0 },
|
||||
};
|
||||
string_construct(&reader->buffer);
|
||||
}
|
||||
|
||||
void file_char_reader_destroy(FileCharReader* reader)
|
||||
{
|
||||
string_destroy(&reader->buffer);
|
||||
@ -515,7 +520,11 @@ break_loop:
|
||||
|
||||
Token lexer_token(const Lexer* lexer, TokenType type, Pos pos)
|
||||
{
|
||||
return (Token) { type, pos, .length = lexer->pos.index - pos.index };
|
||||
return (Token) {
|
||||
.type = type,
|
||||
.pos = pos,
|
||||
.length = lexer->pos.index - pos.index,
|
||||
};
|
||||
}
|
||||
|
||||
void lexer_step(Lexer* lexer)
|
||||
@ -526,6 +535,7 @@ void lexer_step(Lexer* lexer)
|
||||
} else if (!lexer_done(lexer)) {
|
||||
lexer->pos.col += 1;
|
||||
}
|
||||
lexer->pos.index += 1;
|
||||
lexer->current = lexer->reader->next(lexer->reader);
|
||||
}
|
||||
|
||||
|
@ -9,16 +9,16 @@
|
||||
#define PANIC(...) \
|
||||
(fprintf(stderr, "panic: "), \
|
||||
fprintf(stderr, __VA_ARGS__), \
|
||||
fprintf(stderr, ", at %s:%d in %s()", __FILE__, __LINE__, __func__), \
|
||||
fprintf(stderr, ", at %s:%d in %s()\n", __FILE__, __LINE__, __func__), \
|
||||
exit(1));
|
||||
|
||||
#define ASSERT(CONDITION) \
|
||||
{ \
|
||||
if (!(CONDITION)) { \
|
||||
(fprintf(stderr, "assert failed: "), \
|
||||
(fprintf(stderr, "assertion failed: "), \
|
||||
fprintf( \
|
||||
stderr, \
|
||||
"(%s), at %s:%d in %s()", \
|
||||
"(%s), at %s:%d in %s()\n", \
|
||||
#CONDITION, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
|
@ -29,7 +29,9 @@ int main(int argc, const char** argv)
|
||||
|
||||
String ast_string;
|
||||
string_construct(&ast_string);
|
||||
|
||||
expr_vec_stringify(&ast, &ast_string);
|
||||
|
||||
printf("ast = %s\n", ast_string.data);
|
||||
string_destroy(&ast_string);
|
||||
|
||||
|
90
src/parser.c
90
src/parser.c
@ -36,7 +36,6 @@ void expr_vec_push(ExprVec* vec, Expr expr)
|
||||
void expr_vec_stringify(const ExprVec* vec, String* acc)
|
||||
{
|
||||
string_append_cstr(acc, "[");
|
||||
printf("helo worl\n");
|
||||
if (vec->length > 0) {
|
||||
expr_stringify(&vec->exprs[0], acc);
|
||||
for (size_t i = 1; i < vec->length; ++i) {
|
||||
@ -77,9 +76,9 @@ Expr list_expr_construct(Pos pos, ExprVec exprs)
|
||||
return (Expr) { ExprTypeList, pos, .list = exprs };
|
||||
}
|
||||
|
||||
Expr quote_expr_construct(Pos pos, ExprVec exprs)
|
||||
Expr s_expr_construct(Pos pos, ExprVec exprs)
|
||||
{
|
||||
return (Expr) { ExprTypeQuote, pos, .quote = exprs };
|
||||
return (Expr) { ExprTypeS, pos, .s = exprs };
|
||||
}
|
||||
|
||||
void expr_destroy(Expr* expr)
|
||||
@ -99,8 +98,8 @@ void expr_destroy(Expr* expr)
|
||||
case ExprTypeList:
|
||||
expr_vec_destroy(&expr->list);
|
||||
break;
|
||||
case ExprTypeQuote:
|
||||
expr_vec_destroy(&expr->quote);
|
||||
case ExprTypeS:
|
||||
expr_vec_destroy(&expr->s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -126,23 +125,23 @@ void expr_stringify(const Expr* expr, String* acc)
|
||||
);
|
||||
break;
|
||||
case ExprTypeList:
|
||||
string_append_cstr(acc, "List(");
|
||||
string_append_cstr(acc, "[");
|
||||
if (expr->list.length > 0) {
|
||||
expr_stringify(&expr->list.exprs[0], acc);
|
||||
for (size_t i = 1; i < expr->list.length; ++i) {
|
||||
string_append_cstr(acc, ", ");
|
||||
string_append_cstr(acc, " ");
|
||||
expr_stringify(&expr->list.exprs[i], acc);
|
||||
}
|
||||
}
|
||||
string_append_cstr(acc, ")");
|
||||
string_append_cstr(acc, "]");
|
||||
break;
|
||||
case ExprTypeQuote:
|
||||
string_append_cstr(acc, "Quote(");
|
||||
if (expr->quote.length > 0) {
|
||||
expr_stringify(&expr->quote.exprs[0], acc);
|
||||
for (size_t i = 1; i < expr->quote.length; ++i) {
|
||||
string_append_cstr(acc, ", ");
|
||||
expr_stringify(&expr->quote.exprs[i], acc);
|
||||
case ExprTypeS:
|
||||
string_append_cstr(acc, "(");
|
||||
if (expr->s.length > 0) {
|
||||
expr_stringify(&expr->s.exprs[0], acc);
|
||||
for (size_t i = 1; i < expr->s.length; ++i) {
|
||||
string_append_cstr(acc, " ");
|
||||
expr_stringify(&expr->s.exprs[i], acc);
|
||||
}
|
||||
}
|
||||
string_append_cstr(acc, ")");
|
||||
@ -194,10 +193,10 @@ Expr parser_parse_expr(Parser* parser)
|
||||
return parser_parse_char(parser);
|
||||
case TokenTypeString:
|
||||
return parser_parse_string(parser);
|
||||
case TokenTypeLParen:
|
||||
return parser_parse_list(parser);
|
||||
case TokenTypeLBracket:
|
||||
return parser_parse_quote(parser);
|
||||
return parser_parse_list(parser);
|
||||
case TokenTypeLParen:
|
||||
return parser_parse_s(parser);
|
||||
default:
|
||||
PARSER_ADD_ERROR(
|
||||
parser,
|
||||
@ -213,11 +212,10 @@ Expr parser_parse_expr(Parser* parser)
|
||||
Expr parser_parse_id(Parser* parser)
|
||||
{
|
||||
Token token = parser->current;
|
||||
StringSlice slice
|
||||
= parser->reader->value(parser->reader, token.pos.index, token.length);
|
||||
String value;
|
||||
string_from_slice(
|
||||
&value,
|
||||
parser->reader->value(parser->reader, token.pos.index, token.length)
|
||||
);
|
||||
string_from_slice(&value, slice);
|
||||
parser_step(parser);
|
||||
return id_expr_construct(token.pos, value);
|
||||
}
|
||||
@ -301,29 +299,6 @@ Expr parser_parse_string(Parser* parser)
|
||||
}
|
||||
|
||||
Expr parser_parse_list(Parser* parser)
|
||||
{
|
||||
Pos pos = parser->current.pos;
|
||||
parser_step(parser);
|
||||
ExprVec exprs;
|
||||
expr_vec_construct(&exprs);
|
||||
while (parser->current.type != TokenTypeEof
|
||||
&& parser->current.type != TokenTypeRParen) {
|
||||
expr_vec_push(&exprs, parser_parse_expr(parser));
|
||||
}
|
||||
if (parser->current.type != TokenTypeRParen) {
|
||||
PARSER_ADD_ERROR(
|
||||
parser,
|
||||
pos,
|
||||
"expected `]`, got `%s`",
|
||||
token_type_value(parser->current.type)
|
||||
)
|
||||
} else {
|
||||
parser_step(parser);
|
||||
}
|
||||
return quote_expr_construct(pos, exprs);
|
||||
}
|
||||
|
||||
Expr parser_parse_quote(Parser* parser)
|
||||
{
|
||||
Pos pos = parser->current.pos;
|
||||
parser_step(parser);
|
||||
@ -343,7 +318,30 @@ Expr parser_parse_quote(Parser* parser)
|
||||
} else {
|
||||
parser_step(parser);
|
||||
}
|
||||
return quote_expr_construct(pos, exprs);
|
||||
return list_expr_construct(pos, exprs);
|
||||
}
|
||||
|
||||
Expr parser_parse_s(Parser* parser)
|
||||
{
|
||||
Pos pos = parser->current.pos;
|
||||
parser_step(parser);
|
||||
ExprVec exprs;
|
||||
expr_vec_construct(&exprs);
|
||||
while (parser->current.type != TokenTypeEof
|
||||
&& parser->current.type != TokenTypeRParen) {
|
||||
expr_vec_push(&exprs, parser_parse_expr(parser));
|
||||
}
|
||||
if (parser->current.type != TokenTypeRParen) {
|
||||
PARSER_ADD_ERROR(
|
||||
parser,
|
||||
pos,
|
||||
"expected `]`, got `%s`",
|
||||
token_type_value(parser->current.type)
|
||||
)
|
||||
} else {
|
||||
parser_step(parser);
|
||||
}
|
||||
return s_expr_construct(pos, exprs);
|
||||
}
|
||||
|
||||
void parser_step(Parser* parser)
|
||||
|
10
src/parser.h
10
src/parser.h
@ -13,7 +13,7 @@ typedef enum {
|
||||
ExprTypeChar,
|
||||
ExprTypeString,
|
||||
ExprTypeList,
|
||||
ExprTypeQuote,
|
||||
ExprTypeS,
|
||||
} ExprType;
|
||||
|
||||
typedef struct Expr Expr;
|
||||
@ -28,6 +28,7 @@ void expr_vec_construct(ExprVec* vec);
|
||||
void expr_vec_destroy(ExprVec* vec);
|
||||
void expr_vec_push(ExprVec* vec, Expr expr);
|
||||
void expr_vec_stringify(const ExprVec* vec, String* acc);
|
||||
void expr_vec_stringify_tree(const ExprVec* vec, String* acc, int depth);
|
||||
|
||||
struct Expr {
|
||||
ExprType type;
|
||||
@ -38,7 +39,7 @@ struct Expr {
|
||||
char char_value;
|
||||
String string_value;
|
||||
ExprVec list;
|
||||
ExprVec quote;
|
||||
ExprVec s;
|
||||
};
|
||||
};
|
||||
|
||||
@ -48,9 +49,10 @@ Expr int_expr_construct(Pos pos, int64_t value);
|
||||
Expr char_expr_construct(Pos pos, char value);
|
||||
Expr string_expr_construct(Pos pos, String value);
|
||||
Expr list_expr_construct(Pos pos, ExprVec exprs);
|
||||
Expr quote_expr_construct(Pos pos, ExprVec exprs);
|
||||
Expr s_expr_construct(Pos pos, ExprVec exprs);
|
||||
void expr_destroy(Expr* expr);
|
||||
void expr_stringify(const Expr* expr, String* acc);
|
||||
void expr_stringify_depth(const Expr* expr, String* acc, int depth);
|
||||
|
||||
typedef struct {
|
||||
const CharReader* reader;
|
||||
@ -69,7 +71,7 @@ Expr parser_parse_int(Parser* parser);
|
||||
Expr parser_parse_char(Parser* parser);
|
||||
Expr parser_parse_string(Parser* parser);
|
||||
Expr parser_parse_list(Parser* parser);
|
||||
Expr parser_parse_quote(Parser* parser);
|
||||
Expr parser_parse_s(Parser* parser);
|
||||
void parser_step(Parser* parser);
|
||||
|
||||
#endif
|
||||
|
5
src/runtime.c
Normal file
5
src/runtime.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "runtime.h"
|
||||
|
||||
void value_vec_construct(ValueVec* vec, Alloc* alloc) { }
|
||||
|
||||
void value_vec_destroy(ValueVec* vec) { }
|
48
src/runtime.h
Normal file
48
src/runtime.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef RUNTIME_H
|
||||
#define RUNTIME_H
|
||||
|
||||
#include "lexer.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct Alloc {
|
||||
void* (*alloc)(struct Alloc* alloc, size_t size);
|
||||
} Alloc;
|
||||
|
||||
typedef enum {
|
||||
ValueTypeSymbol,
|
||||
ValueTypeInt,
|
||||
ValueTypeChar,
|
||||
ValueTypeBool,
|
||||
ValueTypeList,
|
||||
} ValueType;
|
||||
|
||||
typedef struct Value Value;
|
||||
|
||||
typedef struct {
|
||||
Alloc* alloc;
|
||||
Value* data;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
} ValueVec;
|
||||
|
||||
void value_vec_construct(ValueVec* vec, Alloc* alloc);
|
||||
void value_vec_destroy(ValueVec* vec);
|
||||
|
||||
struct Value {
|
||||
ValueType type;
|
||||
union {
|
||||
int64_t int_value;
|
||||
char char_value;
|
||||
bool bool_value;
|
||||
String string_value;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
} Runtime;
|
||||
|
||||
void runtime_construct(Runtime* runtime);
|
||||
void runtime_destroy(Runtime* runtime);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user