initial parser

This commit is contained in:
Zack Buhman 2025-02-23 23:46:42 -06:00
parent 9ee311b464
commit c8321747f6
7 changed files with 186 additions and 0 deletions

7
assert.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#if defined(__dreamcast__)
#include "assert_dreamcast.h"
#else
#include "assert_hosted.h"
#endif

41
assert_dreamcast.h Normal file
View File

@ -0,0 +1,41 @@
#pragma once
#include "printf.h"
#include "class_file.h"
#define assert(b) \
do { \
if (!(b)) { \
printf("%s:%d %s: assertion `%s` failed\n", __FILE__, __LINE__, __func__, #b); \
while (1); \
} \
} while (0);
static inline void assert_print_string(struct constant * constant)
{
for (int i = 0; i < constant->utf8.length; i++) {
printc(constant->utf8.bytes[i]);
}
printc('\n');
}
#define assertvm(vm, b) \
do { \
if (!(b)) { \
printf("%s:%d %s: vm assertion `%s` failed\n", __FILE__, __LINE__, __func__, #b); \
\
struct class_entry * class_entry = vm->current_frame->class_entry; \
struct constant * class_constant = &class_entry->class_file->constant_pool[class_entry->class_file->this_class - 1]; \
assert(class_constant->tag == CONSTANT_Class); \
struct constant * class_name_constant = &class_entry->class_file->constant_pool[class_constant->class.name_index - 1]; \
assert(class_name_constant->tag == CONSTANT_Utf8); \
assert_print_string(class_name_constant); \
\
struct method_info * method_info = vm->current_frame->method; \
struct constant * method_name_constant = &class_entry->class_file->constant_pool[method_info->name_index - 1]; \
assert(method_name_constant->tag == CONSTANT_Utf8); \
assert_print_string(method_name_constant); \
\
while (1); \
} \
} while (0);

16
assert_hosted.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
extern void __assert_fail (const char *__assertion, const char *__file,
unsigned int __line, const char *__function)
__attribute__ ((__noreturn__));
#define __ASSERT_FUNCTION __func__
#define assert(expr) \
({ \
if (!(expr)) \
__assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION); \
})
#define fail(expr) \
(__assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION);)

47
ast.h Normal file
View File

@ -0,0 +1,47 @@
#pragma once
struct token;
struct expression {
struct token * constant;
};
enum statement_type {
STATEMENT_RETURN,
STATEMENT_IF,
STATEMENT_IF_ELSE,
};
struct statement;
struct statement_return {
struct expression * expression;
};
struct statement_if {
struct expression * expression;
struct statement * statement;
};
struct statement_if_else {
struct expression * expression;
struct statement * statement;
};
struct statement {
enum statement_type type;
union {
struct statement_return * statement_return;
struct statement_if * statement_if;
struct statement_if_else * statement_if_else;
};
};
struct function_definition {
struct token * name;
struct statement * statements;
};
struct program {
struct function_definition * function_definition;
};

7
grammar.txt Normal file
View File

@ -0,0 +1,7 @@
<program> ::= <function>
<function> ::= "int" <identifier> "(" "void" ")" "{" <statement> "}"
<statement> ::= "return" <exp> ";" | "if" "(" <exp> ")" <statement> [ "else" <statement> ]
<statement> ::= "return" <exp> ";"
<exp> ::= <int>
<identifier> ::= ? An identifier token ?
<int> ::= ? A constant token ?

33
malloc.c Normal file
View File

@ -0,0 +1,33 @@
#include "assert.h"
#include "malloc.h"
struct arena {
uint8_t * mem;
uint32_t size;
uint32_t ix;
};
static uint8_t class_mem[0x100000];
struct arena class_arena = {
.mem = class_mem,
.size = (sizeof (class_mem)),
.ix = 0,
};
void malloc_class_arena_reset()
{
class_arena.ix = 0;
}
void * malloc_class_arena(uint32_t size)
{
if (size == 0)
return nullptr;
assert((class_arena.ix & (~3)) == class_arena.ix);
void * ptr = &class_arena.mem[class_arena.ix];
size = (size + 3) & (~3);
class_arena.ix += size;
return ptr;
}

35
parser.c Normal file
View File

@ -0,0 +1,35 @@
#include "parser.h"
#include "lexer.h"
#include "assert.h"
struct token_reader {
bool have_token;
struct token token;
struct lexer_state lexer_state;
};
struct token peek(struct token_reader * reader)
{
if (reader->have_token) {
return reader->token;
} else {
reader->token = lexer_next_token(reader->lexer_state);
reader->have_token = true;
return reader->token;
}
}
struct token consume(struct token_reader * reader)
{
struct token token = peek(reader);
reader->have_token = false;
}
void expect_type(struct token_reader * reader, enum token_type token_type)
{
struct token token = consume(reader);
if (!(token->type == token_type)) {
printf("token->type=%d token_type=%d\n", token->type, token_type);
fail(token->type == token_type);
}
}