Browse Source

code gen stuff

master
Martin Dørum 3 years ago
parent
commit
cb63015ed1

+ 10
- 0
include/lang2/bytecode.h View File

*/ */
L2_OP_ALLOC_NAMESPACE, L2_OP_ALLOC_NAMESPACE,


/*
* Set a namespace's name to a value.
* Pop <key>
* Pop <val>
* Read <ns>
* Assign <val> to <ns[<key>]>
* Push <val>
*/
L2_OP_NAMESPACE_SET,

/* /*
* Halt execution. * Halt execution.
*/ */

+ 11
- 1
include/lang2/gen/gen.h View File

#define L2_GEN_H #define L2_GEN_H


#include "../io.h" #include "../io.h"
#include "../strset.h"


void l2_gen_stack_frame(struct l2_bufio_writer *writer);
struct l2_generator {
struct l2_strset atoms;
struct l2_strset strings;
struct l2_bufio_writer writer;
};

void l2_gen_init(struct l2_generator *gen);
void l2_gen_free(struct l2_generator *gen);
void l2_gen_stack_frame(struct l2_generator *gen);
void l2_gen_assignment(struct l2_generator *gen, char **ident);


#endif #endif

+ 2
- 0
include/lang2/parse/lex.h View File

L2_TOK_CLOSE_BRACKET, L2_TOK_CLOSE_BRACKET,
L2_TOK_COMMA, L2_TOK_COMMA,
L2_TOK_PERIOD, L2_TOK_PERIOD,
L2_TOK_COLON_EQ,
L2_TOK_EOF, L2_TOK_EOF,
L2_TOK_NUMBER, L2_TOK_NUMBER,
L2_TOK_STRING, L2_TOK_STRING,
L2_TOK_IDENT,
L2_TOK_ERROR, L2_TOK_ERROR,
}; };



+ 2
- 14
include/lang2/parse/parse.h View File

#define L2_PARSE_H #define L2_PARSE_H


#include "lex.h" #include "lex.h"
#include "../io.h"
#include "../strset.h"
#include "gen/gen.h"


struct l2_parse_state {
struct l2_lexer *lexer;
struct l2_bufio_writer writer;
struct l2_strset atoms;
struct l2_strset strings;
};

void l2_parse_init(
struct l2_parse_state *state,
struct l2_lexer *lexer, struct l2_io_writer *w);
void l2_parse_free(struct l2_parse_state *state);
void l2_parse_program(struct l2_parse_state *state);
void l2_parse_program(struct l2_lexer *lexer, struct l2_generator *gen);


#endif #endif

+ 1
- 1
include/lang2/strset.h View File



void l2_strset_init(struct l2_strset *set); void l2_strset_init(struct l2_strset *set);
void l2_strset_free(struct l2_strset *set); void l2_strset_free(struct l2_strset *set);
size_t l2_strset_put_move(struct l2_strset *set, char **str);
size_t l2_strset_put(struct l2_strset *set, char **str);
size_t l2_strset_put_copy(struct l2_strset *set, const char *str); size_t l2_strset_put_copy(struct l2_strset *set, const char *str);
size_t l2_strset_get(struct l2_strset *set, const char *str); size_t l2_strset_get(struct l2_strset *set, const char *str);



+ 21
- 4
lib/gen/gen.c View File



#include "bytecode.h" #include "bytecode.h"


static void put(struct l2_bufio_writer *writer, l2_word word) {
l2_bufio_put_n(writer, &word, sizeof(word));
static void put(struct l2_generator *gen, l2_word word) {
l2_bufio_put_n(&gen->writer, &word, sizeof(word));
} }


void l2_gen_stack_frame(struct l2_bufio_writer *writer) {
put(writer, L2_OP_ALLOC_NAMESPACE);
void l2_gen_init(struct l2_generator *gen) {
l2_strset_init(&gen->atoms);
l2_strset_init(&gen->strings);
}

void l2_gen_free(struct l2_generator *gen) {
l2_strset_free(&gen->atoms);
l2_strset_free(&gen->strings);
}

void l2_gen_stack_frame(struct l2_generator *gen) {
put(gen, L2_OP_ALLOC_NAMESPACE);
}

void l2_gen_assignment(struct l2_generator *gen, char **ident) {
size_t atom_id = l2_strset_put(&gen->atoms, ident);
put(gen, L2_OP_PUSH);
put(gen, atom_id);
put(gen, L2_OP_NAMESPACE_SET);
} }

+ 78
- 0
lib/parse/lex.c View File

return "comma"; return "comma";
case L2_TOK_PERIOD: case L2_TOK_PERIOD:
return "period"; return "period";
case L2_TOK_COLON_EQ:
return "period";
case L2_TOK_EOF: case L2_TOK_EOF:
return "end-of-file"; return "end-of-file";
case L2_TOK_NUMBER: case L2_TOK_NUMBER:
return "number"; return "number";
case L2_TOK_STRING: case L2_TOK_STRING:
return "string"; return "string";
case L2_TOK_IDENT:
return "ident";
case L2_TOK_ERROR: case L2_TOK_ERROR:
return "error"; return "error";
} }
l2_bufio_reader_init(&lexer->reader, r); l2_bufio_reader_init(&lexer->reader, r);
} }


static int peek_ch(struct l2_lexer *lexer) {
int ch = l2_bufio_peek(&lexer->reader, 1);
return ch;
}

static int read_ch(struct l2_lexer *lexer) { static int read_ch(struct l2_lexer *lexer) {
int ch = l2_bufio_get(&lexer->reader); int ch = l2_bufio_get(&lexer->reader);
lexer->ch += 1; lexer->ch += 1;
} }
} }


static void read_ident(struct l2_lexer *lexer, struct l2_token *tok) {
tok->kind = L2_TOK_IDENT;
tok->v.str = malloc(16);
if (tok->v.str == NULL) {
tok->kind = L2_TOK_ERROR;
tok->v.str = "Allocaton failure";
return;
}

size_t size = 16;
size_t idx = 0;

while (1) {
int ch = peek_ch(lexer);

if (is_whitespace(ch)) {
return;
}

switch (ch) {
case '(':
case ')':
case '{':
case '}':
case '[':
case ']':
case ',':
case '.':
case ':':
case EOF:
return;
}

tok->v.str[idx++] = (char)read_ch(lexer);
if (idx >= size) {
size *= 2;
char *newbuf = realloc(tok->v.str, size);
if (newbuf == NULL) {
free(tok->v.str);
tok->kind = L2_TOK_ERROR;
tok->v.str = "Allocation failure";
return;
}

tok->v.str = newbuf;
}
}
}

static void read_tok(struct l2_lexer *lexer, struct l2_token *tok) { static void read_tok(struct l2_lexer *lexer, struct l2_token *tok) {
skip_whitespace(lexer); skip_whitespace(lexer);


tok->kind = L2_TOK_PERIOD; tok->kind = L2_TOK_PERIOD;
break; break;


case ':':
{
ch = read_ch(lexer);
switch (ch) {
case '=':
tok->kind = L2_TOK_COLON_EQ;
break;

default:
tok->kind = L2_TOK_ERROR;
tok->v.str = "Unexpected character";
break;
}
}
break;

case EOF: case EOF:
tok->kind = L2_TOK_EOF; tok->kind = L2_TOK_EOF;
break; break;
case '"': case '"':
read_string(lexer, tok); read_string(lexer, tok);
break; break;

default:
read_ident(lexer, tok);
break;
} }
} }



+ 18
- 13
lib/parse/parse.c View File



#include "gen/gen.h" #include "gen/gen.h"


void l2_parse_init(
struct l2_parse_state *state,
struct l2_lexer *lexer, struct l2_io_writer *w) {
state->lexer = lexer;
l2_bufio_writer_init(&state->writer, w);
l2_strset_init(&state->atoms);
l2_strset_init(&state->strings);
}
static void parse_expression(struct l2_lexer *lexer, struct l2_generator *gen) {
struct l2_token *tok = l2_lexer_peek(lexer, 1);
struct l2_token *tok2 = l2_lexer_peek(lexer, 2);


void l2_parse_free(struct l2_parse_state *state) {
l2_strset_free(&state->atoms);
l2_strset_free(&state->strings);
if (tok->kind == L2_TOK_IDENT && tok2->kind == L2_TOK_COLON_EQ) {
parse_expression(lexer, gen);
l2_gen_assignment(gen, &tok->v.str);
}
} }


void l2_parse_program(struct l2_parse_state *state) {
l2_gen_stack_frame(&state->writer);
void l2_parse_program(struct l2_lexer *lexer, struct l2_generator *gen) {
l2_gen_stack_frame(gen);

while (1) {
struct l2_token *tok = l2_lexer_peek(lexer, 1);
if (tok->kind == L2_TOK_EOF) {
break;
}

parse_expression(lexer, gen);
}
} }

+ 1
- 1
lib/strset.c View File

free(set->vals); free(set->vals);
} }


size_t l2_strset_put_move(struct l2_strset *set, char **str) {
size_t l2_strset_put(struct l2_strset *set, char **str) {
if (set->len >= set->size / 2) { if (set->len >= set->size / 2) {
grow(set); grow(set);
} }

Loading…
Cancel
Save