#include "parse.h" #include #include void parse_init(am_t *am, parse_ctx_t *out) { out->am = am; out->state = PARSE_STATE_INIT; out->sp = out->stack + PARSE_MAX_DEPTH - 1; } static void push_state(parse_ctx_t *ctx, parse_state_t state) { assert(ctx->sp >= ctx->stack); *ctx->sp-- = state; } static parse_state_t pop_state(parse_ctx_t *ctx) { assert(ctx->sp < ctx->stack + PARSE_MAX_DEPTH - 1); return *++ctx->sp; } parse_state_t parse_proc(parse_ctx_t *ctx, const token_t *token) { switch (ctx->state) { case PARSE_STATE_INIT: switch (token->type) { case TOKEN_TYPE_INTEGER: AM_EXPR(ctx->am) = expr_integer(ctx->am, token->integer); ctx->state = PARSE_STATE_DONE; break; case TOKEN_TYPE_SYMBOL: AM_EXPR(ctx->am) = expr_symbol(ctx->am, &token->symbol); ctx->state = PARSE_STATE_DONE; break; case TOKEN_TYPE_OPEN_PAREN: push_state(ctx, PARSE_STATE_DONE); AM_EXPR(ctx->am) = expr_empty_list(ctx->am); ctx->state = PARSE_STATE_LIST; break; case TOKEN_TYPE_CLOSE_PAREN: ctx->state = PARSE_STATE_ERROR; break; } break; case PARSE_STATE_LIST: switch (token->type) { case TOKEN_TYPE_INTEGER: AM_VAL(ctx->am) = expr_integer(ctx->am, token->integer); am_append(ctx->am, EXPR, VAL); break; case TOKEN_TYPE_SYMBOL: AM_VAL(ctx->am) = expr_symbol(ctx->am, &token->symbol); am_append(ctx->am, EXPR, VAL); break; case TOKEN_TYPE_OPEN_PAREN: am_push(ctx->am, EXPR); push_state(ctx, PARSE_STATE_LIST); AM_EXPR(ctx->am) = expr_empty_list(ctx->am); ctx->state = PARSE_STATE_LIST; break; case TOKEN_TYPE_CLOSE_PAREN: ctx->state = pop_state(ctx); if (ctx->state == PARSE_STATE_LIST) { AM_VAL(ctx->am) = AM_EXPR(ctx->am); am_pop(ctx->am, EXPR); am_append(ctx->am, EXPR, VAL); } break; } break; case PARSE_STATE_DONE: case PARSE_STATE_ERROR: break; } assert(ctx->state != PARSE_STATE_INIT); return ctx->state; }