Exemple #1
0
int parse_db(struct _asm_context *asm_context, int null_term_flag)
{
  char token[TOKENLEN];
  int token_type;
  int data32;

  if (asm_context->segment == SEGMENT_BSS)
  {
    printf("Error: .bss segment doesn't support initialized data at %s:%d\n", asm_context->filename, asm_context->line);
    return -1;
  }

  while(1)
  {
    token_type = tokens_get(asm_context, token, TOKENLEN);
    if (token_type == TOKEN_EOL || token_type == TOKEN_EOF) break;

    if (token_type == TOKEN_QUOTED)
    {
      uint8_t *s = (uint8_t *)token;
      while(*s != 0)
      {
        if (*s == '\\')
        {
          int e = tokens_escape_char(asm_context, s);
          if (e == 0)
          {
            return -1;
          }
          s = s + e;
        }

        memory_write_inc(asm_context, *s, DL_DATA);

        asm_context->data_count++;
        s++;
      }

      if (null_term_flag == 1)
      {
        memory_write_inc(asm_context, 0, DL_DATA);
        asm_context->data_count++;
      }
    }
      else
    {
      tokens_push(asm_context, token, token_type);
      if (eval_expression(asm_context, &data32) != 0)
      {
        if (asm_context->pass == 2)
        {
          return -1;
        }

        eat_operand(asm_context);
        data32 = 0;
      }

      if (data32 < -128 || data32 > 0xff)
      {
        print_error_range("db", -128, 0xff, asm_context);
        return -1;
      }

      memory_write_inc(asm_context, (uint8_t)data32, DL_DATA);
      asm_context->data_count++;
    }

    token_type = tokens_get(asm_context, token, TOKENLEN);
    if (token_type == TOKEN_EOL || token_type == TOKEN_EOF) { break; }

    if (IS_NOT_TOKEN(token,','))
    {
      print_error_expecting(",", token, asm_context);
      return -1;
    }
  }

  asm_context->line++;

  return 0;
}
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;
}