Beispiel #1
0
Datei: v7.c Projekt: di3online/v7
enum v7_err v7_call(struct v7 *v7, int num_args) {
  struct v7_val **top = v7_top(v7), **v = top - (num_args + 1), *f = v[0];

  if (v7->no_exec) return V7_OK;
  CHECK(v7->sp > num_args, V7_INTERNAL_ERROR);
  CHECK(f->type == V7_FUNC || f->type == V7_C_FUNC, V7_CALLED_NON_FUNCTION);

  // Return value will substitute function objest on a stack
  v[0] = v7_mkval(v7, V7_UNDEF);  // Set return value to 'undefined'
  v[0]->ref_count++;

  if (f->type == V7_FUNC) {
    const char *src = v7->cursor;
    v7->cursor = f->v.func;     // Move control flow to function body
    TRY(parse_function_definition(v7, v, num_args));  // Execute function body
    v7->cursor = src;           // Return control flow
    if (v7_top(v7) > top) {     // If function body pushed some value on stack,
      free_val(v7, v[0]);
      v[0] = top[0];            // use that value as return value
      v[0]->ref_count++;
    }
  } else if (f->type == V7_C_FUNC) {
    f->v.c_func(v7, v7->cur_obj, v[0], v + 1, num_args);
  }
  free_val(v7, f);

  TRY(inc_stack(v7, - (int) (v7_top(v7) - (v + 1))));  // Clean up stack
  return V7_OK;
}
Beispiel #2
0
program_ptr Parser::parse_program()
{
    int start_line = current_lexeme().line();
    instructions program_body;
    instructions functions;
    instruction_ptr instruction = instruction_ptr();
    
    while (match_current_lexeme(kEndofLine))
        next_line();
    
    while (!finished() && ErrorHandler::is_ok())
    {
        instruction = instruction_ptr();
        
        instruction = parse_function_definition();
        
        if (instruction)
        {
            functions.push_back(instruction);
            continue;
        }
        
        instruction = parse_instruction();
        
        if (!instruction)
        {
            report_current_syntax_error();
            return program_ptr();
        }
        
        program_body.push_back(instruction);
    }
    
    return program_ptr(new Program(start_line, program_body, functions));
}
Beispiel #3
0
Datei: v7.c Projekt: di3online/v7
//  factor  =   number | string_literal | "(" expression ")" |
//              variable | "this" | "null" | "true" | "false" |
//              "{" object_literal "}" |
//              "[" array_literal "]" |
//              function_definition |
//              function_call
static enum v7_err parse_factor(struct v7 *v7) {
  int old_sp = v7_sp(v7);

  if (*v7->cursor == '(') {
    TRY(match(v7, '('));
    TRY(parse_expression(v7));
    TRY(match(v7, ')'));
  } else if (*v7->cursor == '\'' || *v7->cursor == '"') {
    TRY(parse_string_literal(v7));
  } else if (*v7->cursor == '{') {
    TRY(parse_object_literal(v7));
  } else if (is_alpha(*v7->cursor) || *v7->cursor == '_') {
    TRY(parse_identifier(v7));
    if (test_token(v7, "this", 4)) {
      inc_stack(v7, 1);
      v7_top(v7)[-1] = &v7->scopes[v7->current_scope];
    } else if (test_token(v7, "null", 4)) {
      TRY(v7_make_and_push(v7, V7_NULL));
    } else if (test_token(v7, "true", 4)) {
      TRY(v7_make_and_push(v7, V7_BOOL));
      v7_top(v7)[-1]->v.num = 1;
    } else if (test_token(v7, "false", 5)) {
      TRY(v7_make_and_push(v7, V7_BOOL));
      v7_top(v7)[-1]->v.num = 0;
    } else if (test_token(v7, "function", 8)) {
      TRY(parse_function_definition(v7, NULL, 0));
    } else if (test_token(v7, "delete", 6)) {
      TRY(parse_delete(v7));
    } else {
      TRY(parse_variable(v7));
    }
  } else {
    TRY(parse_num(v7));
  }

  if (*v7->cursor == '(') {
    TRY(parse_function_call(v7));
  }

  // Don't leave anything on stack if no execution flag is set
  if (v7->no_exec) {
    inc_stack(v7, old_sp - v7->sp);
  }

  return V7_OK;
}
Beispiel #4
0
Node Parser::Parse(const std::vector<token> &ntokens)
{
	std::vector<token> tokens = ntokens;

	Node root;
	root.kind = NODE_PROGRAM;

	_current = &tokens.front();

	while (_current->kind != TOKEN_EOF) {
		if (_current->kind == TOKEN_WORD) {
			std::string definition_name = _current->word;
			if (peek_next_token()->kind == TOKEN_OPENING_PAREN)
				root.next.push_back(parse_function_definition());
			else
				root.next.push_back(parse_constant_definition());
		} else {
			error("Unexpected top level token, expected word");
		}
	}

	return root;
}
Beispiel #5
0
char *
parse_cell(Maze *maze, Functions *functions, char cell_str[2], char *f_ptr, char *f_end, Cell *cell)
{
  if (str_eq(cell_str, "^^", 2))
  {
    cell->type = CELL_START;
  }
  else if (str_eq(cell_str, "..", 2))
  {
    cell->type = CELL_PATH;
  }
  else if (str_eq(cell_str, "##", 2) ||
           str_eq(cell_str, "  ", 2) ||
           str_eq(cell_str, "``", 2))
  {
    cell->type = CELL_WALL;
  }
  else if (str_eq(cell_str, "()", 2))
  {
    cell->type = CELL_HOLE;
  }
  else if (str_eq(cell_str, "<>", 2))
  {
    cell->type = CELL_SPLITTER;
  }
  else if (isLetter(cell_str[0]) && (isLetter(cell_str[1]) || isNum(cell_str[1])))
  {
    char *end_function_name_f_ptr = f_ptr + 2;
    char *end_function_definition_f_ptr = parse_function_definition(functions, cell_str, end_function_name_f_ptr, f_end, cell);
    if (end_function_definition_f_ptr != end_function_name_f_ptr)
    {
      f_ptr = end_function_definition_f_ptr;
    }
    else
    {
      cell->type = CELL_FUNCTION;
      cell->function_index = get_function_index(cell_str);
    }

  }
  else if (str_eq(cell_str, "--", 2))
  {
    cell->type = CELL_ONCE;
  }
  else if ((cell_str[0] == '*') && ((cell_str[1] == 'U') ||
                                    (cell_str[1] == 'u')))
  {
    cell->type = CELL_UP_UNLESS_DETECT;
  }
  else if ((cell_str[0] == '*') && ((cell_str[1] == 'D') ||
                                    (cell_str[1] == 'd')))
  {
    cell->type = CELL_DOWN_UNLESS_DETECT;
  }
  else if ((cell_str[0] == '*') && ((cell_str[1] == 'L') ||
                                    (cell_str[1] == 'l')))
  {
    cell->type = CELL_LEFT_UNLESS_DETECT;
  }
  else if ((cell_str[0] == '*') && ((cell_str[1] == 'R') ||
                                    (cell_str[1] == 'r')))
  {
    cell->type = CELL_RIGHT_UNLESS_DETECT;
  }
  else if (str_eq(cell_str, ">>", 2))
  {
    cell->type = CELL_OUT;
  }
  else if (str_eq(cell_str, "<<", 2))
  {
    cell->type = CELL_INP;
  }
  else if ((cell_str[0] == '%') && ((cell_str[1] == 'U') ||
                                    (cell_str[1] == 'u')))
  {
    cell->type = CELL_UP;
  }
  else if ((cell_str[0] == '%') && ((cell_str[1] == 'D') ||
                                    (cell_str[1] == 'd')))
  {
    cell->type = CELL_DOWN;
  }
  else if ((cell_str[0] == '%') && ((cell_str[1] == 'L') ||
                                    (cell_str[1] == 'l')))
  {
    cell->type = CELL_LEFT;
  }
  else if ((cell_str[0] == '%') && ((cell_str[1] == 'R') ||
                                    (cell_str[1] == 'r')))
  {
    cell->type = CELL_RIGHT;
  }
  else if (isNum(cell_str[0]) && isNum(cell_str[1]))
  {
    cell->type = CELL_PAUSE;

    u32 digit0 = cell_str[0] - '0';
    u32 digit1 = cell_str[1] - '0';
    cell->pause = (10 * digit0) + digit1;
  }

  if (cell->type != CELL_NULL)
  {
    f_ptr += 2;
  }

  return f_ptr;
}