/** 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; }
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); } } }
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; } } } }
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; }