Ejemplo n.º 1
0
struct vm_value *
vm_value_build_math_op(struct vm_state *vm, int operation,
                                            struct vm_value *lhs,
                                            struct vm_value *rhs)
{
   struct vm_value *res;
   LLVMOpcode opcode;

   res = vm_value_new(lhs->type_specifier, "");

   switch (operation) {
      case AST_ADD:
         opcode = (res->type_specifier == TYPE_INT) ? LLVMAdd : LLVMFAdd;
         break;
      case AST_SUB:
         opcode = (res->type_specifier == TYPE_INT) ? LLVMSub : LLVMFSub;
         break;
      case AST_MUL:
         opcode = (res->type_specifier == TYPE_INT) ? LLVMMul: LLVMFMul;
         break;
      case AST_DIV:
         opcode = (res->type_specifier == TYPE_INT) ? LLVMSDiv: LLVMFDiv;
         break;
      default:
         fprintf(stderr, "Unknown math operation: %d\n", operation);
         exit(EXIT_FAILURE);
   }

   res->llvm_value = LLVMBuildBinOp(vm->builder, opcode, lhs->llvm_value,
                                                         rhs->llvm_value, "");
   return res;
}
Ejemplo n.º 2
0
static LLVMValueRef build_from_tokens(char **tokens, int ntokens,
                                      LLVMBuilderRef builder,
                                      LLVMValueRef param) {
  LLVMValueRef stack[MAX_DEPTH];
  int depth = 0;
  int i;

  for (i = 0; i < ntokens; i++) {
    char tok = tokens[i][0];
    switch (tok) {
    case '+':
    case '-':
    case '*':
    case '/':
    case '&':
    case '|':
    case '^':
      if (depth < 2) {
        printf("stack underflow\n");
        return NULL;
      }

      stack[depth - 2] = LLVMBuildBinOp(builder, op_to_opcode(tok),
                                        stack[depth - 1], stack[depth - 2], "");
      depth--;

      break;

    case '@': {
      LLVMValueRef off;

      if (depth < 1) {
        printf("stack underflow\n");
        return NULL;
      }

      off = LLVMBuildGEP(builder, param, &stack[depth - 1], 1, "");
      stack[depth - 1] = LLVMBuildLoad(builder, off, "");

      break;
    }

    default: {
      char *end;
      long val = strtol(tokens[i], &end, 0);
      if (end[0] != '\0') {
        printf("error parsing number\n");
        return NULL;
      }

      if (depth >= MAX_DEPTH) {
        printf("stack overflow\n");
        return NULL;
      }

      stack[depth++] = LLVMConstInt(LLVMInt64Type(), val, 1);
      break;
    }
    }
  }

  if (depth < 1) {
    printf("stack underflow at return\n");
    return NULL;
  }

  LLVMBuildRet(builder, stack[depth - 1]);

  return stack[depth - 1];
}