git » unicorn-sparkle-basic.git » master » tree

[master] / parse.c

/*
 * This file is part of Unicorn Sparkle Basic and is released under
 * CC0 1.0 Universal License.  See LICENSE.txt file or
 * https://creativecommons.org/publicdomain/zero/1.0/ for full license
 * text.
 */

#include "types.h"
#include "parse.h"
#include <gc.h>
#include <stdio.h>

struct node_tag *ast_last_read;

static struct node_tag *ast_alloc(enum NODE_TYPE node_type) {
  struct node_tag *new_node = GC_malloc(sizeof(struct node_tag));
  new_node->type = node_type;
  return new_node;
}

struct node_tag *ast_make_string(char *s) {
  struct node_tag *new_node = ast_alloc(NODE_STRING);
  new_node->data.string.str = s;
  return new_node;
}

struct node_tag *ast_make_numbered_line(double line, struct node_tag *stmt) {
  struct node_tag *new_node = ast_alloc(NODE_NUMBERED_LINE);
  new_node->data.line.linum = line;
  new_node->data.line.stmt = stmt;
  ast_last_read = new_node;
  return new_node;
}

struct node_tag *ast_make_command_run() {
  struct node_tag *new_node = ast_alloc(NODE_COMMAND_RUN);
  ast_last_read = new_node;
  return new_node;
}

struct node_tag *ast_make_print(struct node_tag *expr) {
  struct node_tag *new_node = ast_alloc(NODE_PRINT);
  new_node->data.print.expr = expr;
  return new_node;
}

struct node_tag *ast_make_if(struct node_tag *pred, struct node_tag *stmt) {
  struct node_tag *new_node = ast_alloc(NODE_IF);
  new_node->data.iff.pred = pred;
  new_node->data.iff.stmt = stmt;
  return new_node;
}

struct node_tag *ast_make_id(char *name) {
  struct node_tag *new_node = ast_alloc(NODE_ID);
  new_node->data.id.name = name;
  return new_node;
}

struct node_tag *ast_make_number(double val) {
  struct node_tag *new_node = ast_alloc(NODE_NUMBER);
  new_node->data.number.val = val;
  return new_node;
}

struct node_tag *read_line(char *line) {
  int yyparse_failed;
  yy_scan_string(line);
  yyparse_failed = yyparse();
  yylex_destroy();
  return yyparse_failed ? NULL : ast_last_read;
}

struct node_tag *read_line_stdin(char *prompt) {
  char *line = NULL;
  struct node_tag *read_node;
  line = readline(prompt);
  if (strlen(line) == 0)
    return NULL;
  read_node = read_line(line);
  add_history(line);
  free(line);
  return read_node;
}