~jack/misc

9f433d7aac463a0923f10b5a633afbd8c82369ba — Jack Kelly 6 months ago ce705a4
lambda-c: fix the parser
4 files changed, 30 insertions(+), 5 deletions(-)

M lambda-c/src/lambda.c
M lambda-c/src/lexer.h
M lambda-c/src/lexer.rl
M lambda-c/src/parser.c
M lambda-c/src/lambda.c => lambda-c/src/lambda.c +1 -1
@@ 29,7 29,7 @@
#include "parser.h"

int main(int argc, char *argv[]) {
  g_autoptr(GArray) tokens = lex("(\\x . x)");
  g_autoptr(GArray) tokens = lex("(\\x . \\y . x) y");
  g_autoptr(Term) t = parse(tokens);

  term_fput(t, stdout);

M lambda-c/src/lexer.h => lambda-c/src/lexer.h +2 -0
@@ 4,6 4,7 @@
#include <glib.h>

enum token_type {
  TOKEN_EOF,
  TOKEN_LAMBDA,
  TOKEN_DOT,
  TOKEN_LPAREN,


@@ 16,6 17,7 @@ struct token {
  gchar *v;
};

void token_eof(struct token *t);
void token_lambda(struct token *t);
void token_dot(struct token *t);
void token_lparen(struct token *t);

M lambda-c/src/lexer.rl => lambda-c/src/lexer.rl +10 -0
@@ 41,6 41,11 @@ main := |*
#pragma GCC diagnostic pop

void
token_eof(struct token *t) {
  t->type = TOKEN_EOF;
}

void
token_lambda(struct token *t) {
  t->type = TOKEN_LAMBDA;
}


@@ 74,6 79,9 @@ token_clear(struct token *t) {
void
token_puts(const struct token *t) {
  switch (t->type) {
  case TOKEN_EOF:
    printf("Eof\n");
    return;
  case TOKEN_LAMBDA:
    printf("Lambda\n");
    return;


@@ 111,5 119,7 @@ lex(const gchar *data) {
  struct token t;
  %% write init;
  %% write exec;
  token_eof(&t);
  g_array_append_val(r, t);
  return r;
}

M lambda-c/src/parser.c => lambda-c/src/parser.c +17 -4
@@ 45,22 45,35 @@ static Term* parse_lam(struct parser_state *st) {

static Term* parse_rec(struct parser_state *st) {
  const struct token *t = peek_token(st);
  Term *r;
  switch (t->type) {
  case TOKEN_VAR: return parse_var(st);
  case TOKEN_LAMBDA: return parse_lam(st);
  case TOKEN_VAR:
    r = parse_var(st);
    break;
  case TOKEN_LAMBDA:
    r = parse_lam(st);
    break;
  case TOKEN_LPAREN: {
    expect_token(st, TOKEN_LPAREN);
    Term *r = parse_rec(st);
    r = parse_rec(st);
    expect_token(st, TOKEN_RPAREN);
    return r;
    break;
  }
  case TOKEN_RPAREN:
  case TOKEN_DOT:
  case TOKEN_EOF:
    printf("parse_rec: unexpected token: ");
    token_puts(t);
    abort();
  default: g_assert_not_reached();
  }

  t = peek_token(st);
  if (t->type == TOKEN_EOF || t->type == TOKEN_RPAREN) return r;
  return term_app(r, parse_rec(st));
}

Term*
parse(const GArray *tokens) {
  struct parser_state st = {
    .tokens = tokens,