示例#1
0
文件: vartree.c 项目: dzhus/knr
/**
   Return a pointer to a new empty node for specified variable name.
   Inserting a line into node is expected.
*/
Variable * newVariable(char * name)
{
  Variable * v = allocateVariable();
  v->count = 1;
  v->name = strdup(name);
  v->last_line = NULL;
  v->left = v->right = NULL;
  
  return v;
}
示例#2
0
void Expression::allocateVariables(OperationCode *opcode, Parser* parser) {
	for (list<ExpressionTerm*>::iterator it=postfix.begin(); it!=postfix.end(); it++) {
			Token *token = (*it)->token;
			if (token && (token->aType & Token::OPERATOR) == 0) {
				expressionVars[*it] = setVariable(parser, "");
			}
	}

	for (map<ExpressionTerm*,uint>::iterator it=expressionVars.begin(); it != expressionVars.end(); it++) {
			if (!it->first->token) continue;

			Token *token = it->first->token;

			allocateVariable(opcode, it->second);

			if (token->aType == Token::VARIABLE_FUNCTION) {
				// Copy the original variable into our new one
				opcode->addInterop(new ByteOperation(OP_MOV));

				uint src = getVariableID(parser, token->token);

				opcode->addInterop(new DwordOperation(&it->second));
				opcode->addInterop(new DwordOperation(&src));
			} else {
				// The value to be copied is a numerical value.
				byte operation = 0;
				void *dword = malloc(4);

				if (it->first->token->aType == Token::VARIABLE_INT) {
					operation = OP_MOVI;
					*(int*)dword = atoi(token->token.c_str());
				} else if (token->aType == Token::VARIABLE_FLOAT) {
					operation = OP_MOVF;
					*(float*)dword = (float)atof(token->token.c_str());
				} else {
					throw InvalidTokenException("Invalid token expression of type");
				}

				opcode->addInterop(new ByteOperation(operation));
				opcode->addInterop(new DwordOperation(&it->second));
				opcode->addInterop(new DwordOperation(dword));

				free(dword);
			}
	}
}
示例#3
0
void Expression::handleFunctionCalls(OperationCode *opcode, Parser *parser) {
	for (list<ExpressionTerm*>::iterator it=postfix.begin(); it!=postfix.end(); it++) {
			FunctionCall *fcall = (*it)->func;
			if (fcall) {
				fcall->provideIntermediates(opcode, parser);

				if (postfix.size() > 1) {
					uint id = setVariable(parser, "");

					allocateVariable(opcode, id);
					opcode->addInterop(new ByteOperation(OP_POPMOV));
					opcode->addInterop(new DwordOperation(&id));

					expressionVars[*it] = id;
				}
			}
	}
}
示例#4
0
ParseStatus Parser::parseDecl() {
  Token& name = lex[0];
  Token& op1 = lex[1];
  lex += 2;

  assert(name.isIdentifier());
  assert(resolve(name.text).isNil());
  int slot = allocateVariable(name.text);
  Atom& local = stack[slot];
  local.name_ = name.text;

  // Resolve the type expression if present.
  // TODO(aappleby): Allow complex type expressions.
  if (op1.isOperator(OP_COLON))
  {
    Atom type = resolve(lex[0].text);
    assert(!type.isNil());
    local.type_ = type.name_;
    lex++;
    assert(lex[0].isOperator(OP_EQUALS));
    lex++;
  }

  // Evaluate the right hand side.
  evalExpression();
  skipExpected(TT_DELIMITER, DL_SEMICOLON);
  Atom& value = stack.back();

  // Local type is inferred from the expression.
  if (op1.isOperator(OP_DECLARE)) {
    local.type_ = value.type_;
  } else if (local.type_ != value.type_) {
      // Attempt to convert the item to the given type if necessary.
    if (local.type_ == "int32" && value.type_ == "int64") {
      value.type_ = "int32";
    } else if (local.type_ == "float32" && value.type_ == "float64") {
      value.type_ = "float32";
    } else {
      assert(false);
    }
  }

  if (value.isSymbol()) {
    // Move the expression value to the slot.
    local.setValue(value);
    emit(OC_MOVV, slot, stack.size() - 1);
    emit(OC_POP, 1);
  } else {
    // The result of the right-hand expression is a constant.
    // Store it in the constant table and emit a load instruction to place it
    // in the destination register.
    local.ptype_ = value.ptype_;
    local.value_.blob = value.value_.blob;
    value.setName(name.text);
    assert(local == value);
    int cslot = addConstant(value);
    emit(OC_LOADC, slot, cslot);
  }

  stack.pop();
  return PARSE_OK;
}