initial parser
This commit is contained in:
parent
9ee311b464
commit
c8321747f6
7
assert.h
Normal file
7
assert.h
Normal 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
41
assert_dreamcast.h
Normal 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
16
assert_hosted.h
Normal 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
47
ast.h
Normal 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
7
grammar.txt
Normal 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
33
malloc.c
Normal 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
35
parser.c
Normal 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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user