Exemple #1
0
static struct AstNode *parse_special(
        struct DomNode *dom,
        struct ParserState *state)
{
    struct AstNode *result;

    if ((!err_state() && (result = parse_do_block(dom, state))) ||
        (!err_state() && (result = parse_match(dom, state))) ||
        (!err_state() && (result = parse_if(dom, state))) ||
        (!err_state() && (result = parse_while(dom, state))) ||
        (!err_state() && (result = parse_func_def(dom, state))) ||
        (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_AND, ast_make_spec_bool_and, state))) ||
        (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_OR, ast_make_spec_bool_or, state))) ||
        (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_SET_OF, ast_make_spec_set_of, state))) ||
        (!err_state() && (result = parse_binary(dom, DOM_RES_RANGE_OF, ast_make_spec_range_of, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_ARRAY_OF, ast_make_spec_array_of, state))) ||
        (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_TUPLE_OF, ast_make_spec_tuple_of, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_POINTER_TO, ast_make_spec_pointer_to, state))) ||
        (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_FUNCTION, ast_make_spec_function_type, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_TYPE_PRODUCT, ast_make_spec_type_product, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_TYPE_UNION, ast_make_spec_type_union, state))) ||
        (!err_state() && (result = parse_bind(dom, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_PTR, ast_make_spec_ptr, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_PEEK, ast_make_spec_peek, state))) ||
        (!err_state() && (result = parse_binary(dom, DOM_RES_POKE, ast_make_spec_poke, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_BEGIN, ast_make_spec_begin, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_END, ast_make_spec_end, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_INC, ast_make_spec_inc, state))) ||
        (!err_state() && (result = parse_unary(dom, DOM_RES_SUCC, ast_make_spec_succ, state)))) {
        return result;

    } else {
        return NULL;
    }
}
static int parse_unary(struct _asm_context *asm_context, int64_t *num, int operation)
{
  char token[TOKENLEN];
  int token_type;
  int64_t temp;
  struct _var var;

  var_set_int(&var, 0);

  token_type = tokens_get(asm_context, token, TOKENLEN);

//printf("parse_unary: %s token_type=%d(%d)\n", token, token_type, TOKEN_NUMBER);

  if (IS_TOKEN(token,'-'))
  {
    if (parse_unary(asm_context, &temp, OPER_MINUS) == -1) { return -1; }
  }
    else
  if (IS_TOKEN(token,'~'))
  {
    if (parse_unary(asm_context, &temp, OPER_NOT) != 0) { return -1; }
  }
    else
  if (token_type == TOKEN_NUMBER)
  {
    temp = atoll(token);
  }
    else
  if (IS_TOKEN(token, '('))
  {
    if (eval_expression_ex(asm_context, &var) != 0) { return -1; }
    if (var.type != VAR_INT)
    {
      print_error("Non-integer number in expression", asm_context);
      return -1;
    }

    temp = var_get_int64(&var);

    token_type = tokens_get(asm_context, token, TOKENLEN);
    if (IS_NOT_TOKEN(token,')'))
    {
      print_error_unexp(token, asm_context);
      return -1;
    }
  }
    else
  {
    print_error_unexp(token, asm_context);
    return -1;
  }

  if (operation == OPER_NOT) { *num = ~temp; }
  else if (operation == OPER_MINUS) { *num = -temp; }
  else { print_error_internal(NULL, __FILE__, __LINE__); return -1; }

  return 0;
}
Exemple #3
0
struct node *parse_term(struct compiler *compiler)
{
    struct node *result = parse_unary(compiler);

    while(lexer_current(compiler) == T_MUL || lexer_current(compiler) == T_DIV)
    {
        struct node *node = alloc_node(compiler, N_BINARY_OP);

        node->op = lexer_current(compiler);
        node->left = result;

        lexer_next(compiler);

        node->right = parse_unary(compiler);
        result = node;
    }

    return result;
}
Exemple #4
0
static bool parse_mul(ExprParseState *state)
{
  CHECK_ERROR(parse_unary(state));

  for (;;) {
    switch (state->token) {
      case '*':
        CHECK_ERROR(parse_next_token(state) && parse_unary(state));
        parse_add_func(state, OPCODE_FUNC2, 2, op_mul);
        break;

      case '/':
        CHECK_ERROR(parse_next_token(state) && parse_unary(state));
        parse_add_func(state, OPCODE_FUNC2, 2, op_div);
        break;

      default:
        return true;
    }
  }
}
Exemple #5
0
static BtorNode *
parse_proxy (BtorBTORParser * parser, int len)
{
  return parse_unary (parser, len, btor_copy_exp);
}
Exemple #6
0
static BtorNode *
parse_dec (BtorBTORParser * parser, int len)
{
  return parse_unary (parser, len, btor_dec_exp);
}
static int eval_expression_go(struct _asm_context *asm_context, struct _var *var, struct _operator *last_operator)
{
  char token[TOKENLEN];
  int token_type;
  struct _var var_stack[3];
  int var_stack_ptr = 1;
  struct _operator operator;
  int last_token_was_op = -1;

#ifdef DEBUG
printf("Enter eval_expression_go,  var=%d/%f/%d\n", var_get_int32(var), var_get_float(var), var_get_type(var));
#endif

  memcpy(&operator, last_operator, sizeof(struct _operator));
  VAR_COPY(&var_stack[0], var);

  while(1)
  {
#ifdef DEBUG
printf("eval_expression> going to grab a token\n");
#endif
    token_type = tokens_get(asm_context, token, TOKENLEN);

#ifdef DEBUG
printf("eval_expression> token=%s   var_stack_ptr=%d\n", token, var_stack_ptr);
#endif

    // Issue 15: Return an error if a stack is full with noe operator.
    if (var_stack_ptr == 3 && operator.operation == OPER_UNSET)
    {
      return -1;
    }

    if (token_type == TOKEN_QUOTED)
    {
      if (token[0] == '\\')
      {
        int e = tokens_escape_char(asm_context, (unsigned char *)token);
        if (e == 0) return -1;
        if (token[e+1] != 0)
        {
          print_error("Quoted literal too long.", asm_context);
          return -1;
        }
        sprintf(token, "%d", token[e]);
      }
        else
      {
        if (token[1]!=0)
        {
          print_error("Quoted literal too long.", asm_context);
          return -1;
        }
        sprintf(token, "%d", token[0]);
      }

      token_type = TOKEN_NUMBER;
    }

    // Open and close parenthesis
    if (IS_TOKEN(token,'('))
    {
      if (last_token_was_op == 0 && operator.operation != OPER_UNSET)
      {
        operate(&var_stack[var_stack_ptr-2], &var_stack[var_stack_ptr-1], last_operator);
        var_stack_ptr--;
        operator.operation = OPER_UNSET;

        VAR_COPY(var, &var_stack[var_stack_ptr-1]);
        tokens_push(asm_context, token, token_type);
        return 0;
      }

      if (operator.operation == OPER_UNSET && var_stack_ptr == 2)
      {
        // This is probably the x(r12) case.. so this is actually okay
        VAR_COPY(var, &var_stack[var_stack_ptr-1]);
        tokens_push(asm_context, token, token_type);
        return 0;
      }

      struct _var paren_var;
      struct _operator paren_operator;

      paren_operator.precedence = PREC_UNSET;
      paren_operator.operation = OPER_UNSET;
      memset(&paren_var, 0, sizeof(struct _var));

      if (eval_expression_go(asm_context, &paren_var, &paren_operator) != 0)
      {
        return -1;
      }

      last_token_was_op = 0;

#ifdef DEBUG
printf("Paren got back %d/%f/%d\n", var_get_int32(&paren_var), var_get_float(&paren_var), var_get_type(&paren_var));
#endif

      VAR_COPY(&var_stack[var_stack_ptr++], &paren_var);

      token_type = tokens_get(asm_context, token, TOKENLEN);
      if (!(token[1] == 0 && token[0] == ')'))
      {
        print_error("No matching ')'", asm_context);
        return -1;
      }
      continue;
    }

    if (IS_TOKEN(token,')'))
    {
      tokens_push(asm_context, token, token_type);
      break;
    }

    // End of expression
    if (IS_TOKEN(token,',') || IS_TOKEN(token,']') || token_type == TOKEN_EOF ||
        IS_TOKEN(token,'.'))
    {
      tokens_push(asm_context, token, token_type);
      break;
    }

    if (token_type == TOKEN_EOL)
    {
      //asm_context->tokens.line++;
      tokens_push(asm_context, token, token_type);
      break;
    }

    // Read number
    if (token_type == TOKEN_NUMBER)
    {
      last_token_was_op = 0;

      if (var_stack_ptr == 3)
      {
        print_error_unexp(token, asm_context);
        return -1;
      }

      var_set_int(&var_stack[var_stack_ptr++], atoll(token));
    }
      else
    if (token_type == TOKEN_FLOAT)
    {
      if (var_stack_ptr == 3)
      {
        print_error_unexp(token, asm_context);
        return -1;
      }

      var_set_float(&var_stack[var_stack_ptr++], atof(token));
    }
      else
    if (token_type == TOKEN_SYMBOL)
    {
      last_token_was_op = 1;

      struct _operator operator_prev;
      memcpy(&operator_prev, &operator, sizeof(struct _operator));

      if (get_operator(token, &operator) == -1)
      {
        print_error_unexp(token, asm_context);
        return -1;
      }

      // Issue 15: 2015-July-21 mkohn - If operator is ~ then reverse
      // the next number.
      if (operator.operation == OPER_NOT)
      {
        int64_t num;

        if (parse_unary(asm_context, &num, OPER_NOT) != 0) { return -1; }

        if (var_stack_ptr == 3)
        {
          print_error_unexp(token, asm_context);
          return -1;
        }

        var_set_int(&var_stack[var_stack_ptr++], num);
        memcpy(&operator, &operator_prev, sizeof(struct _operator));

        last_token_was_op = 0;

        continue;
      }

      // Stack pointer probably shouldn't be less than 2
      if (var_stack_ptr == 0)
      {
        printf("Error: Unexpected operator '%s' at %s:%d\n", token, asm_context->tokens.filename, asm_context->tokens.line);
        return -1;
      }

#ifdef DEBUG
printf("TOKEN %s: precedence %d %d\n", token, last_operator->precedence, operator.precedence);
#endif

      if (last_operator->precedence == PREC_UNSET)
      {
        memcpy(last_operator, &operator, sizeof(struct _operator));
      }
        else
      if (last_operator->precedence > operator.precedence)
      {
        if (eval_expression_go(asm_context, &var_stack[var_stack_ptr-1], &operator) == -1)
        {
          return -1;
        }
      }
        else
      {
        operate(&var_stack[var_stack_ptr-2], &var_stack[var_stack_ptr-1], last_operator);
        var_stack_ptr--;
        memcpy(last_operator, &operator, sizeof(struct _operator));
      }
    }
      else
    {
      if (asm_context->pass != 1)
      {
        print_error_unexp(token, asm_context);
      }
      return -1;
    }
  }

#ifdef DEBUG
printf("going to leave  operation=%d\n", last_operator->operation);
PRINT_STACK()
#endif

  if (last_operator->operation != OPER_UNSET)
  {
    operate(&var_stack[var_stack_ptr-2], &var_stack[var_stack_ptr-1], last_operator);
    var_stack_ptr--;
  }

  VAR_COPY(var, &var_stack[var_stack_ptr-1]);

  return 0;
}
Exemple #8
0
static bool parse_unary(ExprParseState *state)
{
  int i;

  switch (state->token) {
    case '+':
      return parse_next_token(state) && parse_unary(state);

    case '-':
      CHECK_ERROR(parse_next_token(state) && parse_unary(state));
      parse_add_func(state, OPCODE_FUNC1, 1, op_negate);
      return true;

    case '(':
      return parse_next_token(state) && parse_expr(state) && state->token == ')' &&
             parse_next_token(state);

    case TOKEN_NUMBER:
      parse_add_op(state, OPCODE_CONST, 1)->arg.dval = state->tokenval;
      return parse_next_token(state);

    case TOKEN_ID:
      /* Parameters: search in reverse order in case of duplicate names -
       * the last one should win. */
      for (i = state->param_names_len - 1; i >= 0; i--) {
        if (STREQ(state->tokenbuf, state->param_names[i])) {
          parse_add_op(state, OPCODE_PARAMETER, 1)->arg.ival = i;
          return parse_next_token(state);
        }
      }

      /* Ordinary builtin constants. */
      for (i = 0; builtin_consts[i].name; i++) {
        if (STREQ(state->tokenbuf, builtin_consts[i].name)) {
          parse_add_op(state, OPCODE_CONST, 1)->arg.dval = builtin_consts[i].value;
          return parse_next_token(state);
        }
      }

      /* Ordinary builtin functions. */
      for (i = 0; builtin_ops[i].name; i++) {
        if (STREQ(state->tokenbuf, builtin_ops[i].name)) {
          int args = parse_function_args(state);

          return parse_add_func(state, builtin_ops[i].op, args, builtin_ops[i].funcptr);
        }
      }

      /* Specially supported functions. */
      if (STREQ(state->tokenbuf, "min")) {
        int cnt = parse_function_args(state);
        CHECK_ERROR(cnt > 0);

        parse_add_op(state, OPCODE_MIN, 1 - cnt)->arg.ival = cnt;
        return true;
      }

      if (STREQ(state->tokenbuf, "max")) {
        int cnt = parse_function_args(state);
        CHECK_ERROR(cnt > 0);

        parse_add_op(state, OPCODE_MAX, 1 - cnt)->arg.ival = cnt;
        return true;
      }

      return false;

    default:
      return false;
  }
}