Example #1
0
Scope *context_scope_push(Context *ctx) {
    Scope *s = scope_create();
    
    Scope *prev = ctx->active_scope;
    ctx->active_scope = s;
    
    if (prev != NULL) {
        scope_child_add(prev, s);
    }
    
    return s;
}
Example #2
0
File: main.c Project: erik/arroyo
int main(int argc, char** argv)
{
  char* filename = NULL;
  int repl_flag=0, help_flag=0;

  struct option long_opts[] = {
    {"help", no_argument, &help_flag, 1},
    {"repl", no_argument, &repl_flag, 1},
    {0,      0,           0,          0}
  };

  int cont = 1;
  while(cont) {
    int opt_index = 0;
    switch(getopt_long(argc, argv, "hr", long_opts, &opt_index)) {
    case -1:
      cont = 0;
      break;

    case 'r':
      repl_flag = 1;
      break;

    case '?':
    case 'h':
      return usage();
    }
  }

  if(optind < argc)
    filename = argv[optind++];

  if((!filename && !repl_flag) || help_flag)
    return usage();

  context* root = context_create();
  root->scope = scope_create(NULL);

  if(filename)
    run_file(filename, root);

  if(repl_flag)
    run_repl(root);

  context_destroy(root);
  return 0;
}
Example #3
0
expr *eval(scope *scope, expr *e) {
  if (e == NULL)
    return NULL;

  switch (e->type) {
  // String and Integer expressions evaluate to themselves.
  case STRING_EXPR:
  case INT_EXPR:
  case FUNC_EXPR:
  case BUILTIN_EXPR:
  case BOOL_EXPR:
    return e;
  case SYMBOL_EXPR: {
    expr *value = scope_lookup(scope, e->string_value);
    // if (!value)
    //  PANIC("Symbol %s not bound to any value\n", e->string_value);
    return value;
  }
  case CELL_EXPR: {
    expr *head = eval(scope, e->head);
    if (head == NULL)
      PANIC("() is not a function.");
    if (head->type == BUILTIN_EXPR) {
      // Call the built-in construct.
      return head->func_ptr(scope, e->tail);
    } else if (head->type == FUNC_EXPR) {
      // Call the function.
      struct scope *new_scope = scope_create(head->closure);

      if (islist(head->arguments)) {
        expr *actuals = e->tail;
        for (expr *formal = head->arguments; formal != NULL; formal = formal->tail) {
          expr *formal_expr = formal->head;
          assert(formal_expr->type == SYMBOL_EXPR);
          if (actuals != NULL) {
            // If this is a regular function, evaluate the argument. Otherwise, return expression,
            // Since macros take in their arguments literally.
            expr *actual_value = head->ismacro ? actuals->head : eval(scope, actuals->head);
            // Bind the actual value to the formal symbol.
            scope_add_mapping(new_scope, formal_expr->string_value, actual_value);
            // Proceed to the next actual.
            actuals = actuals->tail;
          } else {
            // No more actuals, so simply bind the symbol to the empty list (NIL).
            scope_add_mapping(new_scope, formal_expr->string_value, NULL);
          }
        }
      } else if (issymbol(head->arguments)) {
        if (head->ismacro)
          scope_add_mapping(new_scope, head->arguments->string_value, e->tail);
        else
          scope_add_mapping(new_scope, head->arguments->string_value, eval_varargs(scope, e->tail));
      }

      // Evaulate the body of the function
      struct expr *last_value = NULL;
      for (struct expr *statement = head->body; statement != NULL; statement = statement->tail) {
        last_value = eval(new_scope, statement->head);
      }

      // If this is a regular function, we simply return the result.
      return head->ismacro ? eval(scope, last_value) : last_value;
    } else {
      PANIC("Tried to execute something which is not a function or a macro.");
    }
  }
  default:
    PANIC("Unkown expression type.\n");
  }
}