WIP allocator for compiler.
This commit is contained in:
parent
6310390cc4
commit
373caf7b5e
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Plan 9 coding conventions for C (http://man.9front.org/6/style)
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 2
|
||||||
|
TabWidth: 2
|
||||||
|
UseTab: Always
|
||||||
|
|
||||||
|
SpaceBeforeParens: Never
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
RemoveBracesLLVM: true
|
||||||
|
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
PointerAlignment: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
SortIncludes: Never
|
||||||
|
IndentCaseLabels: false
|
||||||
169
lexer.h
169
lexer.h
|
|
@ -4,95 +4,96 @@
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TOKEN_ERROR,
|
TOKEN_ERROR,
|
||||||
TOKEN_EOF,
|
TOKEN_EOF,
|
||||||
TOKEN_IDENTIFIER,
|
TOKEN_IDENTIFIER,
|
||||||
TOKEN_LITERAL_INT,
|
TOKEN_LITERAL_INT,
|
||||||
TOKEN_LITERAL_NAT,
|
TOKEN_LITERAL_NAT,
|
||||||
TOKEN_LITERAL_REAL,
|
TOKEN_LITERAL_REAL,
|
||||||
TOKEN_LITERAL_STR,
|
TOKEN_LITERAL_STR,
|
||||||
TOKEN_TYPE_I8,
|
TOKEN_TYPE_I8,
|
||||||
TOKEN_TYPE_I16,
|
TOKEN_TYPE_I16,
|
||||||
TOKEN_TYPE_INT,
|
TOKEN_TYPE_INT,
|
||||||
TOKEN_TYPE_U8,
|
TOKEN_TYPE_U8,
|
||||||
TOKEN_TYPE_U16,
|
TOKEN_TYPE_U16,
|
||||||
TOKEN_TYPE_NAT,
|
TOKEN_TYPE_NAT,
|
||||||
TOKEN_TYPE_REAL,
|
TOKEN_TYPE_REAL,
|
||||||
TOKEN_TYPE_STR,
|
TOKEN_TYPE_STR,
|
||||||
TOKEN_TYPE_BOOL,
|
TOKEN_TYPE_BOOL,
|
||||||
TOKEN_TYPE_VOID,
|
TOKEN_TYPE_VOID,
|
||||||
TOKEN_TYPE_PTR,
|
TOKEN_TYPE_PTR,
|
||||||
TOKEN_KEYWORD_PLEX,
|
TOKEN_KEYWORD_PLEX,
|
||||||
TOKEN_KEYWORD_FN,
|
TOKEN_KEYWORD_FN,
|
||||||
TOKEN_KEYWORD_CONST,
|
TOKEN_KEYWORD_CONST,
|
||||||
TOKEN_KEYWORD_IF,
|
TOKEN_KEYWORD_IF,
|
||||||
TOKEN_KEYWORD_IS,
|
TOKEN_KEYWORD_IS,
|
||||||
TOKEN_KEYWORD_AS,
|
TOKEN_KEYWORD_AS,
|
||||||
TOKEN_KEYWORD_ELSE,
|
TOKEN_KEYWORD_ELSE,
|
||||||
TOKEN_KEYWORD_WHILE,
|
TOKEN_KEYWORD_WHILE,
|
||||||
TOKEN_KEYWORD_FOR,
|
TOKEN_KEYWORD_FOR,
|
||||||
TOKEN_KEYWORD_RETURN,
|
TOKEN_KEYWORD_RETURN,
|
||||||
TOKEN_KEYWORD_USE,
|
TOKEN_KEYWORD_USE,
|
||||||
TOKEN_KEYWORD_INIT,
|
TOKEN_KEYWORD_INIT,
|
||||||
TOKEN_KEYWORD_THIS,
|
TOKEN_KEYWORD_THIS,
|
||||||
TOKEN_KEYWORD_GLOBAL,
|
TOKEN_KEYWORD_GLOBAL,
|
||||||
TOKEN_KEYWORD_OPEN,
|
TOKEN_KEYWORD_OPEN,
|
||||||
TOKEN_KEYWORD_READ,
|
TOKEN_KEYWORD_READ,
|
||||||
TOKEN_KEYWORD_WRITE,
|
TOKEN_KEYWORD_WRITE,
|
||||||
TOKEN_KEYWORD_STAT,
|
TOKEN_KEYWORD_STAT,
|
||||||
TOKEN_KEYWORD_CLOSE,
|
TOKEN_KEYWORD_CLOSE,
|
||||||
TOKEN_KEYWORD_LOOP,
|
TOKEN_KEYWORD_LOOP,
|
||||||
TOKEN_KEYWORD_DO,
|
TOKEN_KEYWORD_DO,
|
||||||
TOKEN_KEYWORD_NIL,
|
TOKEN_KEYWORD_NIL,
|
||||||
TOKEN_KEYWORD_TRUE,
|
TOKEN_KEYWORD_TRUE,
|
||||||
TOKEN_KEYWORD_FALSE,
|
TOKEN_KEYWORD_FALSE,
|
||||||
TOKEN_OPERATOR_NOT,
|
TOKEN_OPERATOR_NOT,
|
||||||
TOKEN_OPERATOR_AND,
|
TOKEN_OPERATOR_AND,
|
||||||
TOKEN_OPERATOR_OR,
|
TOKEN_OPERATOR_OR,
|
||||||
TOKEN_BANG,
|
TOKEN_BANG,
|
||||||
TOKEN_BANG_EQ,
|
TOKEN_BANG_EQ,
|
||||||
TOKEN_EQ,
|
TOKEN_EQ,
|
||||||
TOKEN_EQ_EQ,
|
TOKEN_EQ_EQ,
|
||||||
TOKEN_AND,
|
TOKEN_AND,
|
||||||
TOKEN_AND_AND,
|
TOKEN_AND_AND,
|
||||||
TOKEN_PIPE,
|
TOKEN_PIPE,
|
||||||
TOKEN_PIPE_PIPE,
|
TOKEN_PIPE_PIPE,
|
||||||
TOKEN_QUESTION,
|
TOKEN_QUESTION,
|
||||||
TOKEN_QUESTION_DOT,
|
TOKEN_QUESTION_DOT,
|
||||||
TOKEN_PLUS,
|
TOKEN_PLUS,
|
||||||
TOKEN_MINUS,
|
TOKEN_MINUS,
|
||||||
TOKEN_STAR,
|
TOKEN_STAR,
|
||||||
TOKEN_SLASH,
|
TOKEN_SLASH,
|
||||||
TOKEN_MESH,
|
TOKEN_MESH,
|
||||||
TOKEN_BIG_MONEY,
|
TOKEN_BIG_MONEY,
|
||||||
TOKEN_GT,
|
TOKEN_GT,
|
||||||
TOKEN_LT,
|
TOKEN_LT,
|
||||||
TOKEN_GTE,
|
TOKEN_GTE,
|
||||||
TOKEN_LTE,
|
TOKEN_LTE,
|
||||||
TOKEN_DOT,
|
TOKEN_DOT,
|
||||||
TOKEN_COMMA,
|
TOKEN_COMMA,
|
||||||
TOKEN_COLON,
|
TOKEN_COLON,
|
||||||
TOKEN_CARET,
|
TOKEN_CARET,
|
||||||
TOKEN_SEMICOLON,
|
TOKEN_SEMICOLON,
|
||||||
TOKEN_LPAREN,
|
TOKEN_LPAREN,
|
||||||
TOKEN_RPAREN,
|
TOKEN_RPAREN,
|
||||||
TOKEN_LBRACE,
|
TOKEN_LBRACE,
|
||||||
TOKEN_RBRACE,
|
TOKEN_RBRACE,
|
||||||
TOKEN_LBRACKET,
|
TOKEN_LBRACKET,
|
||||||
TOKEN_RBRACKET,
|
TOKEN_RBRACKET,
|
||||||
TOKEN_ARROW_RIGHT
|
TOKEN_ARROW_RIGHT
|
||||||
} TokenType;
|
} TokenType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct token_s Token;
|
||||||
TokenType type;
|
struct token_s {
|
||||||
const char *start;
|
TokenType type;
|
||||||
i32 length;
|
const char *start;
|
||||||
i32 line;
|
i32 length;
|
||||||
} Token;
|
i32 line;
|
||||||
|
};
|
||||||
|
|
||||||
void init_lexer(const char *source);
|
void init_lexer(const char *source);
|
||||||
Token next_token();
|
Token next_token();
|
||||||
const char* token_type_to_string(TokenType type);
|
const char *token_type_to_string(TokenType type);
|
||||||
char peek();
|
char peek();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
134
libc.c
134
libc.c
|
|
@ -1,72 +1,96 @@
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
|
|
||||||
void mcpy(void *to, void *from, u32 length) {
|
void
|
||||||
u8 *src, *dest;
|
mcpy(void *to, void *from, u32 length)
|
||||||
if (to == nil || from == nil) return;
|
{
|
||||||
|
u8 *src, *dest;
|
||||||
|
if(to == nil || from == nil) return;
|
||||||
|
|
||||||
src = (u8 *)from;
|
src = (u8 *)from;
|
||||||
dest = (u8 *)to;
|
dest = (u8 *)to;
|
||||||
|
|
||||||
while (length-- > 0) {
|
while(length-- > 0) *(dest++) = *(src++);
|
||||||
*(dest++) = *(src++);
|
return;
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 scpy(char *to, const char *from, u32 length) {
|
i32
|
||||||
u32 i;
|
scpy(char *to, const char *from, u32 length)
|
||||||
if (to == nil || from == nil) return -1;
|
{
|
||||||
if (length == 0) {return 0;}
|
u32 i;
|
||||||
for (i = 0; i < length - 1 && from[i] != '\0'; i++) {
|
if(to == nil || from == nil) return -1;
|
||||||
to[i] = from[i];
|
if(length == 0) return 0;
|
||||||
}
|
for(i = 0; i < length - 1 && from[i] != '\0'; i++) to[i] = from[i];
|
||||||
to[i] = '\0';
|
to[i] = '\0';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq(const char *s1, const char *s2) {
|
bool
|
||||||
if (s1 == nil && s2 == nil) return true;
|
seq(const char *s1, const char *s2)
|
||||||
if (s1 == nil || s2 == nil) return false;
|
{
|
||||||
|
if(s1 == nil && s2 == nil) return true;
|
||||||
|
if(s1 == nil || s2 == nil) return false;
|
||||||
|
|
||||||
while (*s1 && *s2) {
|
while(*s1 && *s2) {
|
||||||
if (*s1 != *s2) return false;
|
if(*s1 != *s2) return false;
|
||||||
s1++;
|
s1++;
|
||||||
s2++;
|
s2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*s1 == '\0' && *s2 == '\0');
|
return (*s1 == '\0' && *s2 == '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sleq(const char *s1, const char *s2, u32 length) {
|
bool
|
||||||
u32 i;
|
sleq(const char *s1, const char *s2, u32 length)
|
||||||
if (s1 == nil && s2 == nil) return true;
|
{
|
||||||
if (s1 == nil || s2 == nil) return false;
|
u32 i;
|
||||||
|
if(s1 == nil && s2 == nil) return true;
|
||||||
|
if(s1 == nil || s2 == nil) return false;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < length && *s1 && *s2) {
|
while(i < length && *s1 && *s2) {
|
||||||
if (*s1 != *s2) return false;
|
if(*s1 != *s2) return false;
|
||||||
s1++;
|
s1++;
|
||||||
s2++;
|
s2++;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i == length) return true;
|
if(i == length) return true;
|
||||||
return (*s1 == '\0' && *s2 == '\0');
|
return (*s1 == '\0' && *s2 == '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 slen(const char *str) {
|
u32
|
||||||
u32 i;
|
slen(const char *str)
|
||||||
if (str == nil) {return 0;}
|
{
|
||||||
for (i = 0; str[i] != '\0'; i++) {
|
u32 i;
|
||||||
;
|
if(str == nil) return 0;
|
||||||
}
|
for(i = 0; str[i] != '\0'; i++);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 snlen(const char *str, u32 max_len) {
|
u32
|
||||||
u32 i;
|
snlen(const char *str, u32 max_len)
|
||||||
if (str == nil) {return 0;}
|
{
|
||||||
for (i = 0; i < max_len && str[i] != '\0'; i++) {
|
u32 i;
|
||||||
;
|
if(str == nil) return 0;
|
||||||
}
|
for(i = 0; i < max_len && str[i] != '\0'; i++);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
aaloc(Arena *arena, u32 size)
|
||||||
|
{
|
||||||
|
u32 pos;
|
||||||
|
if(arena == nil) return nil;
|
||||||
|
if(arena->count + size > arena->capacity) return nil;
|
||||||
|
|
||||||
|
pos = arena->count;
|
||||||
|
arena->count += size;
|
||||||
|
return &arena->tape[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
u32
|
||||||
|
afree(Arena *arena)
|
||||||
|
{
|
||||||
|
u32 freed = arena->count;
|
||||||
|
arena->count = 0;
|
||||||
|
return freed;
|
||||||
|
}
|
||||||
|
|
|
||||||
45
libc.h
45
libc.h
|
|
@ -15,21 +15,21 @@
|
||||||
|
|
||||||
#ifdef HAVE_STDINT
|
#ifdef HAVE_STDINT
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
typedef int8_t i8;
|
typedef int8_t i8;
|
||||||
typedef uint16_t u16;
|
typedef uint16_t u16;
|
||||||
typedef int16_t i16;
|
typedef int16_t i16;
|
||||||
typedef uint32_t u32;
|
typedef uint32_t u32;
|
||||||
typedef int32_t i32;
|
typedef int32_t i32;
|
||||||
typedef float f32;
|
typedef float f32;
|
||||||
#else
|
#else
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8;
|
||||||
typedef signed char i8;
|
typedef signed char i8;
|
||||||
typedef unsigned short u16;
|
typedef unsigned short u16;
|
||||||
typedef signed short i16;
|
typedef signed short i16;
|
||||||
typedef unsigned int u32;
|
typedef unsigned int u32;
|
||||||
typedef signed int i32;
|
typedef signed int i32;
|
||||||
typedef float f32;
|
typedef float f32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_STDBOOL
|
#ifdef HAVE_STDBOOL
|
||||||
|
|
@ -44,17 +44,17 @@ typedef u8 bool;
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#define nil NULL
|
#define nil NULL
|
||||||
#else
|
#else
|
||||||
#define nil ((void*)0)
|
#define nil ((void *)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define I8_MIN -128
|
#define I8_MIN -128
|
||||||
#define I8_MAX 127
|
#define I8_MAX 127
|
||||||
#define U8_MAX 255
|
#define U8_MAX 255
|
||||||
|
|
||||||
#define I16_MIN -32768
|
#define I16_MIN -32768
|
||||||
#define I16_MAX 32767
|
#define I16_MAX 32767
|
||||||
#define U16_MAX 65535
|
#define U16_MAX 65535
|
||||||
|
|
||||||
#define I32_MIN -2147483648
|
#define I32_MIN -2147483648
|
||||||
#define I32_MAX 2147483647
|
#define I32_MAX 2147483647
|
||||||
#define U32_MAX 4294967295
|
#define U32_MAX 4294967295
|
||||||
|
|
@ -69,11 +69,20 @@ typedef u8 bool;
|
||||||
|
|
||||||
#define USED(x) ((void)(x))
|
#define USED(x) ((void)(x))
|
||||||
|
|
||||||
|
typedef struct arena_s Arena;
|
||||||
|
struct arena_s {
|
||||||
|
u8 *tape;
|
||||||
|
u32 count;
|
||||||
|
u32 capacity;
|
||||||
|
};
|
||||||
|
|
||||||
void mcpy(void *dest, void *src, u32 n);
|
void mcpy(void *dest, void *src, u32 n);
|
||||||
i32 scpy(char* to, const char *from, u32 length);
|
i32 scpy(char *to, const char *from, u32 length);
|
||||||
bool seq(const char *s1, const char *s2);
|
bool seq(const char *s1, const char *s2);
|
||||||
bool sleq(const char *s1, const char *s2, u32 length);
|
bool sleq(const char *s1, const char *s2, u32 length);
|
||||||
u32 slen(const char *str);
|
u32 slen(const char *str);
|
||||||
u32 snlen(const char *str, u32 max_len);
|
u32 snlen(const char *str, u32 max_len);
|
||||||
|
void *aalloc(Arena *arena, u32 size);
|
||||||
|
u32 afree(Arena *arena);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
36
main.c
36
main.c
|
|
@ -1,24 +1,26 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define EMBED_FILE(name) \
|
#define EMBED_FILE(name) \
|
||||||
void emit_##name(const char *filename) { \
|
void emit_##name(const char *filename) \
|
||||||
FILE *f = fopen(filename, "wb"); \
|
{ \
|
||||||
if (f) { \
|
FILE *f = fopen(filename, "wb"); \
|
||||||
fwrite(name, 1, name##_len, f); \
|
if(f) { \
|
||||||
fclose(f); \
|
fwrite(name, 1, name##_len, f); \
|
||||||
} \
|
fclose(f); \
|
||||||
}
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int
|
||||||
char *name;
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
if (argc > 1) {
|
if(argc > 1)
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
} else {
|
else
|
||||||
name = "'u'";
|
name = "'u'";
|
||||||
}
|
|
||||||
|
|
||||||
printf("nuqneH %s?\n", name);
|
printf("nuqneH %s?\n", name);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
194
parser.c
194
parser.c
|
|
@ -1,51 +1,177 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
bool push(TokenStack *ts, Token t) {
|
Parser parser;
|
||||||
if (ts->count >= ts->capacity) return false;
|
|
||||||
ts->stack[ts->count++] = t;
|
bool
|
||||||
return true;
|
advance()
|
||||||
|
{
|
||||||
|
parser.previous = parser.current;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
parser.current = next_token();
|
||||||
|
if(parser.current.type != TOKEN_ERROR) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Token pop(TokenStack *ts) {
|
bool
|
||||||
if (ts->count == 0) return (Token){TOKEN_ERROR, nil, -1, -1};
|
push(TokenStack *ts, Token t)
|
||||||
return ts->stack[--ts->count];
|
{
|
||||||
|
if(ts->count >= ts->capacity) return false;
|
||||||
|
ts->stack[ts->count++] = t;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token top(TokenStack *ts) {
|
Token
|
||||||
if (ts->count == 0) return (Token){TOKEN_ERROR, nil, -1, -1};
|
pop(TokenStack *ts)
|
||||||
return ts->stack[ts->count - 1];
|
{
|
||||||
|
if(ts->count == 0) return (Token){TOKEN_ERROR, nil, -1, -1};
|
||||||
|
return ts->stack[--ts->count];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool enqueue(TokenQueue *tq, Token t) {
|
Token
|
||||||
if (tq->count >= tq->capacity) return false;
|
top(TokenStack *ts)
|
||||||
|
{
|
||||||
tq->queue[tq->end] = t;
|
if(ts->count == 0) return (Token){TOKEN_ERROR, nil, -1, -1};
|
||||||
tq->end = (tq->end + 1) % tq->capacity; // Wrap around
|
return ts->stack[ts->count - 1];
|
||||||
tq->count++;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Token dequeue(TokenQueue *tq) {
|
bool
|
||||||
if (tq->count == 0) return (Token){TOKEN_ERROR, NULL, -1, -1};
|
enqueue(TokenQueue *tq, Token t)
|
||||||
|
{
|
||||||
Token t = tq->queue[tq->start];
|
if(tq->count >= tq->capacity) return false;
|
||||||
tq->start = (tq->start + 1) % tq->capacity; // Wrap around
|
|
||||||
tq->count--;
|
tq->queue[tq->end] = t;
|
||||||
return t;
|
tq->end = (tq->end + 1) % tq->capacity; // Wrap around
|
||||||
|
tq->count++;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token peek_queue(TokenQueue *tq) {
|
Token
|
||||||
if (tq->count == 0) return (Token){TOKEN_ERROR, NULL, -1, -1};
|
dequeue(TokenQueue *tq)
|
||||||
return tq->queue[tq->start];
|
{
|
||||||
|
if(tq->count == 0) return (Token){TOKEN_ERROR, NULL, -1, -1};
|
||||||
|
|
||||||
|
Token t = tq->queue[tq->start];
|
||||||
|
tq->start = (tq->start + 1) % tq->capacity; // Wrap around
|
||||||
|
tq->count--;
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool expression() {
|
Token
|
||||||
|
peek_queue(TokenQueue *tq)
|
||||||
|
{
|
||||||
|
if(tq->count == 0) return (Token){TOKEN_ERROR, NULL, -1, -1};
|
||||||
|
return tq->queue[tq->start];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compile(char *source) {
|
u32
|
||||||
TokenStack operators;
|
idx_from_arena(Arena *arena, void *p)
|
||||||
TokenQueue output;
|
{
|
||||||
|
return (u32)((u8 *)p - arena->tape);
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ptr_from_arena(Arena *arena, u32 i)
|
||||||
|
{
|
||||||
|
return &arena->tape[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ArenaList *
|
||||||
|
al_create(Arena *arena, u32 size)
|
||||||
|
{
|
||||||
|
ArenaList *meta = aalloc(arena, sizeof(ArenaList));
|
||||||
|
if(!meta) return nil;
|
||||||
|
|
||||||
|
meta->size = size + sizeof(u32);
|
||||||
|
meta->arena = arena;
|
||||||
|
meta->head = 0;
|
||||||
|
meta->tail = 0;
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
al_append(ArenaList *list, void **out_payload)
|
||||||
|
{
|
||||||
|
void *node = aalloc(list->arena, list->size);
|
||||||
|
if(!node) return nil;
|
||||||
|
|
||||||
|
u32 idx = idx_from_arena(list->arena, node);
|
||||||
|
void *payload = node; /* Payload starts at offset 0 */
|
||||||
|
|
||||||
|
void *cdr_ptr = (u8 *)node + (list->size - sizeof(u32));
|
||||||
|
|
||||||
|
*(u32 *)cdr_ptr = 0;
|
||||||
|
|
||||||
|
if(list->tail != 0) {
|
||||||
|
void *prev_node = ptr_from_arena(list->arena, list->tail);
|
||||||
|
void *prev_cdr = (u8 *)prev_node + (list->size - sizeof(u32));
|
||||||
|
*(u32 *)prev_cdr = idx;
|
||||||
|
} else {
|
||||||
|
list->head = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->tail = idx;
|
||||||
|
|
||||||
|
if(out_payload) *out_payload = payload;
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
al_head(ArenaList *list)
|
||||||
|
{
|
||||||
|
if(list->head == 0) return nil;
|
||||||
|
return ptr_from_arena(list->arena, list->head);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
al_tail(ArenaList *list)
|
||||||
|
{
|
||||||
|
if(list->tail == 0) return nil;
|
||||||
|
return ptr_from_arena(list->arena, list->tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolLink *
|
||||||
|
symbol_table_find(ArenaList *table, const char *name)
|
||||||
|
{
|
||||||
|
void *current = al_head(table);
|
||||||
|
Arena *arena = table->arena;
|
||||||
|
|
||||||
|
while(current != nil) {
|
||||||
|
SymbolLink *link = (SymbolLink *)current;
|
||||||
|
|
||||||
|
if(seq(link->s.name.start, name)) return link;
|
||||||
|
|
||||||
|
u32 next_idx = link->cdr;
|
||||||
|
current = (next_idx == 0) ? nil : ptr_from_arena(arena, next_idx);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
* Parser
|
||||||
|
***************************************************/
|
||||||
|
|
||||||
|
bool
|
||||||
|
expression()
|
||||||
|
{
|
||||||
|
Token operator_stack[256];
|
||||||
|
TokenStack operators = {0};
|
||||||
|
operators.stack = operator_stack;
|
||||||
|
operators.capacity = 256;
|
||||||
|
|
||||||
|
Token output_queue[256];
|
||||||
|
TokenQueue output = {0};
|
||||||
|
output.queue = output_queue;
|
||||||
|
output.capacity = 256;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
compile(char *source)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
146
parser.h
146
parser.h
|
|
@ -4,100 +4,92 @@
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
|
|
||||||
typedef enum { GLOBAL, LOCAL, VAR } ScopeType;
|
typedef enum symbol_type_e {
|
||||||
typedef enum {
|
VOID,
|
||||||
VOID,
|
BOOL,
|
||||||
BOOL,
|
I8,
|
||||||
I8,
|
I16,
|
||||||
I16,
|
I32,
|
||||||
I32,
|
U8,
|
||||||
U8,
|
U16,
|
||||||
U16,
|
U32,
|
||||||
U32,
|
F8,
|
||||||
F8,
|
F16,
|
||||||
F16,
|
F32,
|
||||||
F32,
|
STR,
|
||||||
STR,
|
ARRAY,
|
||||||
PLEX,
|
FUNCTION,
|
||||||
ARRAY,
|
PLEX,
|
||||||
FUNCTION
|
METHOD,
|
||||||
|
TRAIT,
|
||||||
} SymbolType;
|
} SymbolType;
|
||||||
|
|
||||||
|
typedef struct arena_list_s ArenaList;
|
||||||
typedef struct symbol_s Symbol;
|
typedef struct symbol_s Symbol;
|
||||||
typedef struct symbol_tab_s SymbolTable;
|
typedef struct symbol_link_s SymbolLink;
|
||||||
typedef struct value_type_s ValueType;
|
|
||||||
typedef struct plex_fields_tab_s PlexFieldsTable;
|
|
||||||
typedef struct plex_def_s PlexDef;
|
|
||||||
typedef struct plex_tab_s PlexTable;
|
|
||||||
typedef struct scope_s Scope;
|
|
||||||
typedef struct scope_tab_s ScopeTable;
|
|
||||||
typedef struct token_stack_s TokenStack;
|
typedef struct token_stack_s TokenStack;
|
||||||
typedef struct queue_s TokenQueue;
|
typedef struct queue_s TokenQueue;
|
||||||
|
typedef struct parser_s Parser;
|
||||||
|
|
||||||
struct value_type_s {
|
|
||||||
SymbolType type;
|
|
||||||
u32 name;
|
|
||||||
u32 size;
|
|
||||||
u32 table_ref; // if it is a heap object
|
|
||||||
};
|
|
||||||
|
|
||||||
struct plex_def_s {
|
|
||||||
u32 name;
|
|
||||||
u32 size;
|
|
||||||
u32 field_ref_start;
|
|
||||||
u32 field_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct plex_fields_tab_s {
|
|
||||||
u32 *plex_refs;
|
|
||||||
ValueType *fields;
|
|
||||||
u32 count;
|
|
||||||
u32 capacity;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct plex_tab_s {
|
|
||||||
PlexDef *symbols;
|
|
||||||
u32 count;
|
|
||||||
u32 capacity;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_SYMBOL_NAME_LENGTH 64
|
|
||||||
struct symbol_s {
|
struct symbol_s {
|
||||||
char name[MAX_SYMBOL_NAME_LENGTH];
|
Token name;
|
||||||
u8 name_length;
|
SymbolType type;
|
||||||
SymbolType type;
|
u32 size;
|
||||||
ScopeType scope;
|
i32 scope;
|
||||||
u32 ref; // vm->mp if global, vm->pc local, register if var
|
union type_def {
|
||||||
u32 size; // size of symbol
|
struct trait_def {
|
||||||
|
u32 field_ref_start; /* reference to field list of symbols */
|
||||||
|
u32 methods_ref_start; /* zero if none */
|
||||||
|
} trait;
|
||||||
|
struct plex_def {
|
||||||
|
u32 field_ref_start; /* reference to field list of symbols */
|
||||||
|
u32 methods_ref_start; /* zero if none */
|
||||||
|
} plex;
|
||||||
|
struct function_def {
|
||||||
|
SymbolType return_type;
|
||||||
|
u32 arguments_ref_start; /* reference to field list of symbols */
|
||||||
|
} function;
|
||||||
|
struct array_def {
|
||||||
|
SymbolType type;
|
||||||
|
u32 length; /* zero means "unbounded" */
|
||||||
|
} array;
|
||||||
|
struct field_def {
|
||||||
|
u32 offset;
|
||||||
|
} field;
|
||||||
|
} def;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_SYMBOLS 256
|
struct symbol_link_s {
|
||||||
struct symbol_tab_s {
|
Symbol s;
|
||||||
Symbol symbols[MAX_SYMBOLS];
|
u32 cdr; /* zero means "end of list" */
|
||||||
u8 count;
|
|
||||||
i32 parent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct scope_tab_s {
|
struct arena_list_s {
|
||||||
SymbolTable *scopes;
|
Arena *arena;
|
||||||
u32 count;
|
u32 head;
|
||||||
u32 capacity;
|
u32 tail;
|
||||||
i32 scope_ref;
|
u32 size;
|
||||||
u32 depth;
|
u32 count;
|
||||||
|
i32 parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct token_stack_s {
|
struct token_stack_s {
|
||||||
Token *stack;
|
Token *stack;
|
||||||
i32 capacity;
|
i32 capacity;
|
||||||
i32 count;
|
i32 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct queue_s {
|
struct queue_s {
|
||||||
Token *queue;
|
Token *queue;
|
||||||
i32 capacity;
|
i32 capacity;
|
||||||
i32 start;
|
i32 start;
|
||||||
i32 end;
|
i32 end;
|
||||||
i32 count;
|
i32 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct parser_s {
|
||||||
|
Token current;
|
||||||
|
Token previous;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool push(TokenStack *ts, Token t);
|
bool push(TokenStack *ts, Token t);
|
||||||
|
|
|
||||||
|
|
@ -3,64 +3,63 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int
|
||||||
FILE *in;
|
main(int argc, char *argv[])
|
||||||
int c;
|
{
|
||||||
long count = 0;
|
FILE *in;
|
||||||
long col = 0;
|
int c;
|
||||||
char *var_name;
|
long count = 0;
|
||||||
char *p;
|
long col = 0;
|
||||||
|
char *var_name;
|
||||||
if (argc != 2) {
|
char *p;
|
||||||
fprintf(stderr, "Usage: %s <input_file>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
in = fopen(argv[1], "rb");
|
if(argc != 2) {
|
||||||
if (!in) {
|
fprintf(stderr, "Usage: %s <input_file>\n", argv[0]);
|
||||||
perror("Error opening input file");
|
return 1;
|
||||||
return 1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var_name = (char *)malloc(strlen(argv[1]) + 1);
|
in = fopen(argv[1], "rb");
|
||||||
if (!var_name) {
|
if(!in) {
|
||||||
perror("Memory allocation failed");
|
perror("Error opening input file");
|
||||||
fclose(in);
|
return 1;
|
||||||
return 1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(var_name, argv[1]);
|
|
||||||
|
|
||||||
for (p = var_name; *p; ++p) {
|
|
||||||
if (!isalnum((unsigned char)*p)) {
|
|
||||||
*p = '_';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("unsigned char %s[] = {\n", var_name);
|
var_name = (char *)malloc(strlen(argv[1]) + 1);
|
||||||
|
if(!var_name) {
|
||||||
|
perror("Memory allocation failed");
|
||||||
|
fclose(in);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
c = fgetc(in);
|
strcpy(var_name, argv[1]);
|
||||||
while (c != EOF) {
|
|
||||||
printf(" 0x%02x", c);
|
|
||||||
count++;
|
|
||||||
|
|
||||||
int next = fgetc(in);
|
for(p = var_name; *p; ++p)
|
||||||
if (next != EOF) {
|
if(!isalnum((unsigned char)*p)) *p = '_';
|
||||||
printf(",");
|
|
||||||
ungetc(next, in);
|
|
||||||
if (++col >= 12) {
|
|
||||||
printf("\n");
|
|
||||||
col = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c = fgetc(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n};\n");
|
|
||||||
printf("unsigned int %s_len = %lu;\n", var_name, count);
|
|
||||||
free(var_name);
|
|
||||||
fclose(in);
|
|
||||||
|
|
||||||
return 0;
|
printf("unsigned char %s[] = {\n", var_name);
|
||||||
|
|
||||||
|
c = fgetc(in);
|
||||||
|
while(c != EOF) {
|
||||||
|
printf(" 0x%02x", c);
|
||||||
|
count++;
|
||||||
|
|
||||||
|
int next = fgetc(in);
|
||||||
|
if(next != EOF) {
|
||||||
|
printf(",");
|
||||||
|
ungetc(next, in);
|
||||||
|
if(++col >= 12) {
|
||||||
|
printf("\n");
|
||||||
|
col = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c = fgetc(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n};\n");
|
||||||
|
printf("unsigned int %s_len = %lu;\n", var_name, count);
|
||||||
|
free(var_name);
|
||||||
|
fclose(in);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue