Browse Source

code gen stuff

master
Martin Dørum 3 years ago
parent
commit
cb63015ed1

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

@@ -117,6 +117,16 @@ enum l2_opcode {
*/
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.
*/

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

@@ -2,7 +2,17 @@
#define L2_GEN_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

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

@@ -12,9 +12,11 @@ enum l2_token_kind {
L2_TOK_CLOSE_BRACKET,
L2_TOK_COMMA,
L2_TOK_PERIOD,
L2_TOK_COLON_EQ,
L2_TOK_EOF,
L2_TOK_NUMBER,
L2_TOK_STRING,
L2_TOK_IDENT,
L2_TOK_ERROR,
};


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

@@ -2,20 +2,8 @@
#define L2_PARSE_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

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

@@ -14,7 +14,7 @@ struct l2_strset {

void l2_strset_init(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_get(struct l2_strset *set, const char *str);


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

@@ -2,10 +2,27 @@

#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

@@ -20,12 +20,16 @@ const char *l2_token_kind_name(enum l2_token_kind kind) {
return "comma";
case L2_TOK_PERIOD:
return "period";
case L2_TOK_COLON_EQ:
return "period";
case L2_TOK_EOF:
return "end-of-file";
case L2_TOK_NUMBER:
return "number";
case L2_TOK_STRING:
return "string";
case L2_TOK_IDENT:
return "ident";
case L2_TOK_ERROR:
return "error";
}
@@ -54,6 +58,11 @@ void l2_lexer_init(struct l2_lexer *lexer, struct l2_io_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) {
int ch = l2_bufio_get(&lexer->reader);
lexer->ch += 1;
@@ -137,6 +146,55 @@ static void read_string(struct l2_lexer *lexer, struct l2_token *tok) {
}
}

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) {
skip_whitespace(lexer);

@@ -177,6 +235,22 @@ static void read_tok(struct l2_lexer *lexer, struct l2_token *tok) {
tok->kind = L2_TOK_PERIOD;
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:
tok->kind = L2_TOK_EOF;
break;
@@ -184,6 +258,10 @@ static void read_tok(struct l2_lexer *lexer, struct l2_token *tok) {
case '"':
read_string(lexer, tok);
break;

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


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

@@ -2,20 +2,25 @@

#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

@@ -67,7 +67,7 @@ void l2_strset_free(struct l2_strset *set) {
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) {
grow(set);
}

Loading…
Cancel
Save