示例#1
0
PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg)
{
    RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), debugger, exec, source, errLine, errMsg);
    if (!program)
        return 0;

    StatementNode* exprStatement = program->singleStatement();
    ASSERT(exprStatement);
    ASSERT(exprStatement->isExprStatement());
    if (!exprStatement || !exprStatement->isExprStatement())
        return 0;

    ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
    ASSERT(funcExpr);
    ASSERT(funcExpr->isFuncExprNode());
    if (!funcExpr || !funcExpr->isFuncExprNode())
        return 0;

    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
    ASSERT(body);
    return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());
}
void IdentifierNode::generateILOCCode(Node* context) {
	if (this->children->size() == 0) { // Variable
		Symbol* symbol = Scope::getSymbol(this->symbol->getText());
		Node* symbolScope = Scope::getScope(this->symbol->getText());
		std::string* varAddressRegisterName = ILOC::getRegister(symbol->getText());
		std::string registerBaseAddress = (symbolScope->getNodeType() == Common::NT_PROGRAM) ? "bss" : "fp";
		std::stringstream symbolOffsetStr;
		symbolOffsetStr << symbol->getOffset();
		ILOC* instruction = new ILOC(Common::ILOC_LOADAI, registerBaseAddress, symbolOffsetStr.str(), *varAddressRegisterName, "");
		this->addInstruction(instruction);
		this->setLastRegister(*varAddressRegisterName);
	} else { // vector
		Symbol* symbol = Scope::getSymbol(this->symbol->getText());
		Node* symbolScope = Scope::getScope(this->symbol->getText());
		std::string* vectorAddressRegisterName = ILOC::getRegister(symbol->getText());
		std::string registerBaseAddress = (symbolScope->getNodeType() == Common::NT_PROGRAM) ? "bss" : "fp";
		std::stringstream symbolOffsetStr;
		symbolOffsetStr << symbol->getOffset();
		ILOC* instruction = new ILOC(Common::ILOC_ADDI, registerBaseAddress, symbolOffsetStr.str(), *vectorAddressRegisterName, "");
		this->addInstruction(instruction);
		std::string lastBaseRegister = *vectorAddressRegisterName;
		std::string* indexRegisterName;
		for (unsigned int i = 0; i < this->children->size(); i++) {
			ExpressionNode* expression = dynamic_cast<ExpressionNode*>(this->children->at(i));
			expression->generateILOCCode(this);
			std::stringstream indexStream;
			indexStream << i;
			std::string* multResultRegisterName = ILOC::getRegister("INST_MULT_VEC_RESULT_" + indexStream.str());
			indexRegisterName = ILOC::getRegister("INDEX_REGISTER_NAME_" + indexStream.str());
			ILOC* instructionMult = new ILOC(Common::ILOC_MULTI, expression->getLastRegister(), "4", *multResultRegisterName, "");
			ILOC* instructionLoadAO = new ILOC(Common::ILOC_LOADA0, lastBaseRegister, *multResultRegisterName, *indexRegisterName, "");
			lastBaseRegister = *indexRegisterName;
			this->addInstruction(instructionMult);
			this->addInstruction(instructionLoadAO);
		}
		this->setLastRegister(*indexRegisterName);
	}
}
示例#3
0
ExpressionNode BinaryOperation::simplify(const ExpressionNode& root) const
{
	ExpressionNode* left = root.getFirstChild();
	if (left != 0)
	{
		if (left->getRight() != 0)
		{
			if ((left->getRight())->getRight() != 0)
			{
				throw ExpressionNode::WrongArityError("> 2 arguments for BinaryOperation");
			}
			return simplify( *left, *(left->getRight()) );
		}
		else
		{
			cerr << left << endl;
			throw ExpressionNode::WrongArityError("only 1 argument for BinaryOperation"); 
		}
	}
	else
	{
		throw ExpressionNode::WrongArityError("No arguments for BinaryOperation");
	}
}
示例#4
0
bool ExpressionNode::operator== (const ExpressionNode& other) const
{
	ExpressionNode *selfptr;
	ExpressionNode *otherptr;
	
	if (getType() == other.getType() && 
		getOperation() == other.getOperation() && 
		getVariable() == other.getVariable() &&
		getValue() == other.getValue() )
	{
		selfptr = firstChild;
		otherptr = other.getFirstChild();
		while (selfptr != 0 && otherptr != 0)
		{
			if (*selfptr == *otherptr)
			{
				selfptr = selfptr->getRight();
				otherptr = otherptr->getRight();
			}
			else
			{
				return false;
			}
		}
		if (selfptr == 0 && otherptr == 0)
		{
			return true;
		}
		else
		{
			assert(selfptr != otherptr);
			return false;
		}
	}
	else
	{	
		return false;
	}
}
示例#5
0
		bool is_declaration_name()
		{
			return op == Lexeme::MUL && value->is_declaration_name();
		};
示例#6
0
		bool is_type_name(Document &document, bool lookup)
		{
			return op == Lexeme::MUL && left->is_type_name(document, lookup) && right->is_type_array();
		};
示例#7
0
bool Addition::isCompatible(const ExpressionNode& term1, const ExpressionNode& term2) const
{
	clog << "checkpoint isAddable(" << term1 << ", " << term2 << ")" << endl;
	
	const ExpressionNode * varpart1(0);
	const ExpressionNode * varpart2(0);
	const ExpressionNode * left;
	const ExpressionNode * right;

	if (term1.getType() == NUMBER)
	{
		varpart1 = 0;
	}
	else if (term1.getType() == OPERATION)
	{
		if (term1.getOperation() == &MULTIPLICATION)
		{
			left = term1.getFirstChild();
			right = left->getRight();
			if (left->getType() == NUMBER)
			{
				varpart1 = right;
			}
			else if (right->getType() == NUMBER)
			{
				varpart1 = left;
			}
			else
			{
				varpart1 = &term1;
			}
		}
		else
		{
			varpart1 = &term1;
		}
	}
	else // VARIABLE
	{
		assert(term1.getType() == VARIABLE);
		varpart1 = &term1;
	}
	
	if (term2.getType() == NUMBER)
	{
		varpart2 = 0;
	}
	else if (term2.getType() == OPERATION)
	{
		if (term2.getOperation() == &MULTIPLICATION)
		{
			left = term2.getFirstChild();
			right = left->getRight();
			if (left->getType() == NUMBER)
			{
				varpart2 = right;
			}
			else if (right->getType() == NUMBER)
			{
				varpart2 = left;
			}
			else
			{
				varpart2 = &term2;
			}
		}
		else
		{
			varpart2 = &term2;
		}
	}
	else // VARIABLE
	{
		assert(term2.getType() == VARIABLE);
		varpart2 = &term2;
	}
	
	if (varpart1 != 0 && varpart2 != 0)
	{
		if (*varpart1 == *varpart2)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		if (varpart1 == 0 && varpart2 == 0)
		{
			// both numbers
			return true;
		}
		else
		{
			return false;
		}
	}
}
示例#8
0
		bool is_type_array()
		{
			return op == Lexeme::MUL && value->is_type_array();
		};
示例#9
0
void ExpressionNode::ScopeAndType(ostream &out, int &numErrors) {
	DeclarationNode *dPtr, *paramPtr, *tempdPtr;
	ExpressionNode *argPtr;
	int argCounter;	
	Types lhs_type, rhs_type, lhs_decl, rhs_decl, returnType;
	bool isUnary, lhs_isArray, rhs_isArray, foundError;
	
	lhs_type = rhs_type = lhs_decl = rhs_decl = returnType = Undefined;	// initialize types to undefined
	lhs_isArray = rhs_isArray = foundError = false;						// initialize booleans to false
	isUnary = true;

	string nameToLookup;

	switch (subKind) {
		case AssignK:
			op = "=";	// populate the op for assignments with "=" to make Op logic work properly
			// intentionally drop through to OpK case...
		case OpK:			
			if (child[0] != NULL) {				
				child[0]->ScopeAndType(out, numErrors);
				lhs_type = ((ExpressionNode *)child[0])->type;			// grab lhs type
				lhs_isArray = child[0]->getIsArray();					
			}
			if (child[1] != NULL) {
				isUnary = false;
				child[1]->ScopeAndType(out, numErrors);
				rhs_type = ((ExpressionNode *)child[1])->type;			// grab lhs type
				rhs_isArray = child[1]->getIsArray();								
			}
		
			lookupTypes(op, lhs_decl, rhs_decl, returnType);	// populate the last three variable from the function

			//DEBUG 
			/*if (lineNumber == 26) {
				cerr << "op: " << op << "\nlhs_decl: " << PrintType(lhs_decl) << " lhs_type: " 
					<< PrintType(lhs_type) << "\nrhs_decl: " << PrintType(rhs_decl)
					<< " rhs_type: " << PrintType(rhs_type) << "\nlhs_isArray: " 
					<< boolalpha << lhs_isArray << "\nrhs_isArray: " << rhs_isArray 
					<< noboolalpha <<  endl;					
			}*/
			//DEBUG 

			// unary ops
			if (isUnary && lhs_type != Error) {
				//check for arrays
				if (lhs_isArray) {
					++numErrors;
					foundError = true;
					// Unary operator array check error
					PrintError(out, 16, lineNumber, op, "", "", 0, 0);
				}
				else if (lhs_type != lhs_decl) {	// do type check on unary op
					++numErrors;
					foundError = true;
					// Unary operator type check error
					PrintError(out, 17, lineNumber, op, PrintType(lhs_decl), PrintType(lhs_type), 0, 0);					
				}
			}
			// binary ops
			else if (!isUnary) {
				// check for arrays
				if (lhs_type != Error && rhs_type != Error && (lhs_isArray || rhs_isArray)) {					
					++numErrors;
					foundError = true;
					// binary operator array check error
					PrintError(out, 16, lineNumber, op, "", "", 0, 0);					
				}
				// check for binary ops that can process different types as long as they are the same
				else if (lhs_type != Error && rhs_type != Error && lhs_decl == Undefined && rhs_decl == Undefined && lhs_type != rhs_type) {
					++numErrors;
					foundError = true;
					// same type required check error
					PrintError(out, 1, lineNumber, op, PrintType(lhs_type), PrintType(rhs_type), 0, 0);										
				}					
				// do type check for strict binary operators
				/*else {
					if (lhs_type != Error && lhs_decl != Undefined && lhs_decl != lhs_type) {
						++numErrors;
						foundError = true;
						// binary lhs type check error
						PrintError(out, 2, lineNumber, op, PrintType(lhs_decl), PrintType(lhs_type), 0, 0);
					}
					if (rhs_type != Error && rhs_decl != Undefined && rhs_decl != rhs_type) {
						++numErrors;
						foundError = true;
						// binary rhs type check error
						PrintError(out, 3, lineNumber, op, PrintType(rhs_decl), PrintType(rhs_type), 0, 0);						
					}
				}*/
				else if (lhs_type != Error && rhs_type != Error) {
					if (lhs_decl != Undefined && lhs_decl != lhs_type) {
						++numErrors;
						foundError = true;
						// binary lhs type check error
						PrintError(out, 2, lineNumber, op, PrintType(lhs_decl), PrintType(lhs_type), 0, 0);
					}
					if (rhs_decl != Undefined && rhs_decl != rhs_type) {
						++numErrors;
						foundError = true;
						// binary rhs type check error
						PrintError(out, 3, lineNumber, op, PrintType(rhs_decl), PrintType(rhs_type), 0, 0);						
					}
				}
			}
			// set the type for this node
			if (foundError || lhs_type == Error || rhs_type == Error)  // propagate the error type to avoid cascading errors
				this->type = Error;
			else {
				if (returnType == Undefined)
					this->type = lhs_type;	
					// if returnType is undefined return the lhs (used for ops that can process multiple types)
				else	
					this->type = returnType;
			}
			break;				
		case IdK:				
			// make sure symbol exists
			dPtr = (DeclarationNode *)symtab->lookup(name.c_str());
			if (dPtr != NULL) {
				// populate this ID node with the type from the symbol table				
				if (dPtr->subKind == FuncK) {
					++numErrors;
					// Cannot use functions like simple variables
					PrintError(out, 21, lineNumber, name, "", "", 0, 0);
					this->type = Error; // don't bother trying to check type if expression
				}
				else
					this->type = dPtr->type;

				this->dPtr = dPtr; // save this link for later in Code Generation
			} 
			else if (dPtr == NULL) {
				++numErrors;
				// this symbol has not been declared error
				PrintError(out, 15, lineNumber, name, "", "", 0, 0);				
				this->type = Error;	// set the type to error to avoid cascading errors
			}
			if (child[0] != NULL) {	// this ID has an indexer
				child[0]->ScopeAndType(out, numErrors);
				if (!(dPtr->isArray)) {	// if the symbol table record does show this ID as an array ...
					++numErrors;
					// can't index nonarray error
					PrintError(out, 4, lineNumber, name, "", "", 0, 0);					
				}
				else if (((ExpressionNode *)child[0])->type != Error &&
						((ExpressionNode *)child[0])->type != Int) {	// index need to be type int
					++numErrors;
					// array index type check error
					PrintError(out, 10, lineNumber, PrintType(((ExpressionNode *)child[0])->type), "", "", 0, 0);					
				}
				
			}
			break;		
		case CallK:
			// make sure symbol exists			
			dPtr = (DeclarationNode *)symtab->lookup(name.c_str());
			this->dPtr = dPtr; // save this link for later in Code Generation
			if (dPtr == NULL) {
				++numErrors;
				// this symbol has not been declared
				PrintError(out, 15, lineNumber, name, "", "", 0, 0);				
				this->type = Error;	// set the type to error to avoid cascading errors
			}
			else if (dPtr->subKind != FuncK) {
				++numErrors;
				// variables cannot be called like functions
				PrintError(out, 20, lineNumber, name, "", "", 0, 0);
			}
			else {	// Process the properly declared functions
				this->type = dPtr->type; // the type of this node is the return type of the function
				paramPtr = (DeclarationNode *)dPtr->child[0];	// set the parameter pointer to the function declaration parameters
				argPtr = (ExpressionNode *)this->child[0];	// set the argument pointer to the call arguments
				argCounter = 1;
				// step through the param and argument lists together
				while (paramPtr != NULL && argPtr != NULL) {
					argPtr->ScopeAndType(out, numErrors);	// process expression in call					
					// do type checks first
					if (paramPtr->type != Error && argPtr->type != Error && paramPtr->type != argPtr->type) {
						++numErrors;
						// type in param list differs from type in argument list error
						PrintError(out, 7, lineNumber, PrintType(paramPtr->type), dPtr->name, "", argCounter, dPtr->lineNumber);						
					}	
					// now check to see if array params are handled correctly
					if (paramPtr->isArray && !(argPtr->getIsArray())) {	// expecting an array type in call						
						++numErrors;
						// Expecting array in current parameter error
						PrintError(out, 9, lineNumber, dPtr->name, "", "", argCounter, dPtr->lineNumber);														
					}
					else if (!paramPtr->isArray && argPtr->getIsArray()) { // not expecting an array type						
						++numErrors;
						// Not Expecting array in current parameter error
						PrintError(out, 13, lineNumber, dPtr->name, "", "", argCounter, dPtr->lineNumber);								
					}
							
					// advanced both pointers to next item in list
					paramPtr = (DeclarationNode *)paramPtr->sibling;
					argPtr = (ExpressionNode *)argPtr->sibling;
					++argCounter;	// increment argument counter
				}
				// check to make sure that both lists are finished - no more params to process
				if (paramPtr != NULL || argPtr != NULL) {
					++numErrors; // one list was shorter then the other
					// Wrong number of params error
					PrintError(out, 18, lineNumber, dPtr->name, "", "", dPtr->lineNumber);					
				}
			}
			break;
		// we already know the type of a constant - handled in Bison code - no need to process here	
	}
	
	// now traverse any sibling nodes
	if (sibling != NULL)
		sibling->ScopeAndType(out, numErrors);
	return;
}
示例#10
0
	bool Parser::parse_statement(StatementList *list)	
	{
		lexer.identify_keywords();
		
		switch(lexeme())
		{
			case Lexeme::KW_IF:
				parse_if(list);
				break;
				
			case Lexeme::KW_WHILE:
				parse_while(list);
				break;
				
			case Lexeme::KW_DO:
				parse_do(list);
				parse_terminator();
				break;

			case Lexeme::KW_RETURN:
				parse_return(list);
				parse_terminator();
				break;
			
			case Lexeme::KW_BREAK:
				parse_break(list);
				parse_terminator();
				break;
			
			case Lexeme::KW_CONTINUE:
				parse_continue(list);
				parse_terminator();
				break;
			
			case Lexeme::KW_CONST:
				step();
				parse_local(true, parse_expression(), list);
				parse_terminator();
				break;
			
			case Lexeme::BRACET_OPEN:
				list->append(parse_block<true, false>(Scope::EMPTY));
				break;
			
			case Lexeme::SEMICOLON:
				step();
				break;
			
			case Lexeme::END:
			case Lexeme::BRACET_CLOSE:
				return false;
	
			default:
				if(is_expression(lexeme()))
				{
					ExpressionNode *node = parse_expression();

					if(lexeme() == Lexeme::IDENT && node->is_type_name(document, false))
						parse_local(false, node, list);
					else
						list->append(node);

					parse_terminator();
				}
				else
					return false;
		}
		
		return true;
	}
示例#11
0
bool AssignVar(CompileInstance &inst, const mtlChars &name, const mtlChars &expr)
{
    mtlChars base_name = GetBaseName(name);
    Definition *type = GetType(inst, base_name);
    if (type == NULL) {
        AddError(inst, "Undeclared variable", name);
        return false;
    }
    if (type->mut != Mutable) {
        AddError(inst, "Modifying a constant", name);
        return false;
    }

    ExpressionNode *tree = GenerateTree(expr);
    if (tree == NULL) {
        AddError(inst, "Malformed expression", expr);
        return false;
    }

    mtlChars          base_mem = GetBaseMembers(name);
    bool              result = true;
    Parser            parser;
    mtlList<mtlChars> ops;
    mtlList<mtlChars> m;
    mtlString         order_str;
    const int         num_lanes = (base_mem.GetSize() > 0) ? base_mem.GetSize() : type->type.size;

    for (int lane = 0; lane < num_lanes; ++lane) {

        order_str.Free();
        const int stack_size = tree->Evaluate(name, order_str, lane, 0);

        PushStack(inst, stack_size);

        order_str.SplitByChar(ops, ';');
        mtlItem<mtlChars> *op = ops.GetFirst();

        while (op != NULL && op->GetItem().GetSize() > 0) {

            parser.SetBuffer(op->GetItem());

            switch (parser.MatchPart("%s+=%s%|%s-=%s%|%s*=%s%|%s/=%s%|%s=%s", m, NULL)) {
            case 0:
                EmitInstruction(inst, swsl::FLT_ADD_MM);
                break;
            case 1:
                EmitInstruction(inst, swsl::FLT_SUB_MM);
                break;
            case 2:
                EmitInstruction(inst, swsl::FLT_MUL_MM);
                break;
            case 3:
                EmitInstruction(inst, swsl::FLT_DIV_MM);
                break;
            case 4:
                EmitInstruction(inst, swsl::FLT_SET_MM);
                break;
            default:
                AddError(inst, "Invalid syntax", op->GetItem());
                return false;
                break;
            }

            mtlItem<swsl::Instruction> *instr_item = inst.program.GetLast();

            const mtlChars dst = m.GetFirst()->GetItem();
            const mtlChars src = m.GetFirst()->GetNext()->GetItem();

            EmitOperand(inst, dst);
            if (src.IsFloat()) {
                *((int*)(&instr_item->GetItem().instr)) += 1;
            }
            EmitOperand(inst, src);

            op = op->GetNext();
        }

        PopStack(inst, stack_size);
    }

    delete tree;

    return result;
}
示例#12
0
// Evaluates and prints a tree version of the active watch list
// The tree will be expanded along the nodes in expansionPath
// Optionally the list is filtered to only show differences from pFilterName (the name of a persisted watch list)
HRESULT WatchCmd::Print(int expansionIndex, __in_z WCHAR* expansionPath, __in_z WCHAR* pFilterName)
{
    HRESULT Status = S_OK;
    INIT_API_EE();
    INIT_API_DAC();
    EnableDMLHolder dmlHolder(TRUE);
    IfFailRet(InitCorDebugInterface());

    PersistList* pFilterList = NULL;
    if(pFilterName != NULL)
    {
        pFilterList = pPersistListHead;
        while(pFilterList != NULL)
        {
            if(_wcscmp(pFilterList->pName, pFilterName)==0)
                break;
            pFilterList = pFilterList->pNext;
        }
    }

    PersistWatchExpression* pHeadFilterExpr = (pFilterList != NULL) ? pFilterList->pHeadExpr : NULL;

    WatchExpression* pExpression = pExpressionListHead;
    int index = 1;
    while(pExpression != NULL)
    {
        ExpressionNode* pResult = NULL;
        if(FAILED(Status = ExpressionNode::CreateExpressionNode(pExpression->pExpression, &pResult)))
        {
            ExtOut("  %d) Error: HRESULT 0x%x while evaluating expression \'%S\'", index, Status, pExpression->pExpression);
        }
        else
        {
            //check for matching absolute expression
            PersistWatchExpression* pCurFilterExpr = pHeadFilterExpr;
            while(pCurFilterExpr != NULL)
            {
                if(_wcscmp(pCurFilterExpr->pExpression, pResult->GetAbsoluteExpression())==0)
                    break;
                pCurFilterExpr = pCurFilterExpr->pNext;
            }

            // check for matching persist evaluation on the matching expression
            BOOL print = TRUE;
            if(pCurFilterExpr != NULL)
            {
                WCHAR pCurPersistResult[MAX_EXPRESSION];
                FormatPersistResult(pCurPersistResult, MAX_EXPRESSION, pResult);
                if(_wcscmp(pCurPersistResult, pCurFilterExpr->pPersistResult)==0)
                {
                    print = FALSE;
                }
            }

            //expand and print
            if(print)
            {
                if(index == expansionIndex)
                    pResult->Expand(expansionPath);
                PrintCallbackData data;
                data.index = index;
                WCHAR pCommand[MAX_EXPRESSION];
                swprintf_s(pCommand, MAX_EXPRESSION, L"!watch -expand %d", index);
                data.pCommand = pCommand;
                pResult->DFSVisit(EvalPrintCallback, (VOID*)&data);
            }
            delete pResult;
        }
        pExpression = pExpression->pNext;
        index++;
    }
    return Status;
}
示例#13
0
		bool is_declaration_name()
		{
			return op == Lexeme::MUL && right->is_declaration_name();
		};
示例#14
0
bool Multiplication::isCompatible(const ExpressionNode& left, const ExpressionNode& right)
{
	if (left.getType() == NUMBER && right.getType() == NUMBER)
	{
		return true;
	}
	else if (left.getType() == VARIABLE && right.getType() == VARIABLE)
	{
		if (left.getVariable() == right.getVariable())
		{
			return true;
		}
	}
	else if (left.getType() == OPERATION)
	{
		if (left.getOperation() == &ADDITION || left.getOperation() == &SUM)
		{
			return true;
		}
		else if (left.getOperation() == &MULTIPLICATION || left.getOperation() == &PRODUCT)
		{
			return true;
		}
	}
	else if (right.getType() == OPERATION)
	{
		if (right.getOperation() == &ADDITION || right.getOperation() == &SUM)
		{
			return true;
		}
		else if (right.getOperation() == &MULTIPLICATION || right.getOperation() == &PRODUCT)
		{
			return true;
		}
	}
	
	return false;
}
示例#15
0
ExpressionNode ChainOperation::simplify(const ExpressionNode& root) const
{
	ExpressionNode* left = root.getFirstChild();
	ExpressionNode* lPtr;
	ExpressionNode* rPtr;
	vector<ExpressionNode *> used;
	ExpressionNode newNode(this);
	bool ending = false;
	
	cout << "ChainOp simplify " << *left << " " <<*left->getRight() << endl;
	
	if (left == 0)
	{
		return ExpressionNode(root.getOperation()->getIdentity());
	}
	else if (left->getRight() == 0)
	{
		return *left;
	}
	else
	{
		for (lPtr=left; lPtr->getRight()!=0; lPtr=lPtr->getRight())
		{
			if (find(used.begin(), used.end(), lPtr) == used.end() ) //if lPtr not in used
			{
				if (lPtr->getOperation() == this || lPtr->getOperation() == pairwiseOp)  // if lPtr is itself the same Chain Operation
				{
					for (ExpressionNode* i = lPtr->getFirstChild(); i!=0; i=i->getRight())
					{
						newNode.appendChild(*i);
					}
					used.push_back(lPtr);
				}
				else
				{
					for (rPtr = lPtr->getRight(); rPtr!=0; rPtr=rPtr->getRight())
					{
						if (find(used.begin(),used.end(),rPtr)==used.end() && pairwiseOp->isCompatible(*lPtr, *rPtr))
						{
							newNode.appendChild(pairwiseOp->simplify(*lPtr,*rPtr));
							used.push_back(lPtr);
							used.push_back(rPtr);
							break;
						}
					}
				}
			}
		}
		if (find(used.begin(), used.end(), lPtr) == used.end() ) // check last child for expansion
		{
			if (lPtr->getOperation() == this || lPtr->getOperation() == pairwiseOp)
			{
				for (ExpressionNode* i = lPtr->getFirstChild(); i!=0; i=i->getRight())
				{
					newNode.appendChild(*i);
				}
				used.push_back(lPtr);
			}
		}
	}
	if (newNode.getFirstChild() == 0)
	{
		ending = true;
	}
	for (lPtr=left; lPtr!=0; lPtr=lPtr->getRight())
	{
		if (find(used.begin(),used.end(),lPtr) == used.end())
		{
			newNode.appendChild(*lPtr);
		}
	}
	if (ending)
	{
		clog << "ending ChainSimplify, root/newNode: " << root << newNode << endl;
		return newNode;
	}
	else
	{
		return simplify(newNode);
	}
}
示例#16
0
ExpressionNode Addition::simplify(ExpressionNode& left, ExpressionNode& right) const
{
	clog << "checkpoint addsimplify" << endl;
	
	//simplest case: at least one side is just 0
	if (left.getType() == NUMBER && left.getValue().getInt() == 0)
	{
		return right;
	}
	else if (right.getType() == NUMBER && right.getValue().getInt() == 0)
	{
		return left;
	}
	
	// for each left term: for each right term: try adding
	
	stack <ExpressionNode*> leftNodeStack;
	ExpressionNode * currentLeftNode = &left;
	bool leftFinished = false;
	stack <ExpressionNode*> rightNodeStack;
	vector <ExpressionNode*> rightDeleteList;
	ExpressionNode * currentRightNode = &right;
	bool rightFinished = false;
	ExpressionNode newNode(&ADDITION);
	
	while (leftFinished == false)
	{
		clog << "looping left" << endl;
		
		if (currentLeftNode->getType() == OPERATION && currentLeftNode->getOperation() == &ADDITION)
		{
			
			if (currentLeftNode->getFirstChild() == 0)
			{
				throw ExpressionNode::WrongArityError();
			}
			currentLeftNode = currentLeftNode->getFirstChild();
			leftNodeStack.push(currentLeftNode);
			continue;
		}
		
		// leaf term on left tree: traverse right tree
		rightFinished = false;
		currentRightNode = &right;
		while (rightFinished == false)
		{
			clog << "looping right" << endl;
			
			if (currentRightNode->getType() == OPERATION && currentRightNode->getOperation() == &ADDITION)
			{
				if (currentRightNode->getFirstChild() == 0)
				{
					throw ExpressionNode::WrongArityError();
				}
				currentRightNode = currentRightNode->getFirstChild();
				rightNodeStack.push(currentRightNode);
				continue;
			}
			assert(currentLeftNode != 0);
			assert(currentRightNode !=0);
			clog << "checkpoint addsimplify: before isAddable(" << *currentLeftNode << ", " << *currentRightNode << ")"<<  endl;
			// leaf terms on both sides: attempt adding
			if (isCompatible(*currentLeftNode, *currentRightNode))
			{
				clog << "checkpoint addsimplify: after isAddable; " << endl;
				clog << *currentLeftNode << " " << *currentRightNode << endl;
				(*currentLeftNode) = addTerms(*currentLeftNode, *currentRightNode);
				clog << "checkpoint addsimplify: after addTerms; " << endl;
				clog << "currentLeftNode: " << *currentLeftNode << " RightNode:" << *currentRightNode << endl;
				clog << "left " << left << "right " << right << endl;
				if (currentRightNode == &right)
				{
					//entire right tree has been assimilated
					return left;
				}
				// try marking for deletion after right loop instead of removing
				rightDeleteList.push_back(currentRightNode);
			}
			while (true)
			{
				clog << "rightNodeStack: " << rightNodeStack.size() << endl;
				if (rightNodeStack.size() != 0) clog << "rightNodeStack.top(): " << *(rightNodeStack.top()) << endl;
				if (rightNodeStack.size() == 0)
				{
					rightFinished = true;
					break;
				}
				currentRightNode = rightNodeStack.top();
				rightNodeStack.pop();
				if (currentRightNode->getRight() != 0)
				{
					currentRightNode = currentRightNode->getRight();
					rightNodeStack.push(currentRightNode);
					break;
				}
			}
		}
		// deleting marked rights
		for (vector<ExpressionNode*>::iterator it = rightDeleteList.begin(); it != rightDeleteList.end(); it++)
		{
			right.remove(*it);
		}
		rightDeleteList.clear();
		clog << "here left: " << left << "right: " << right <<endl;
		
		//clog << "leftNodeStack: " << leftNodeStack.size() << endl;
		//if (leftNodeStack.size() > 0)
		//{
			//clog << "leftNodeStack: " << *(leftNodeStack.top()) << endl;
		//}
		while (true)
		{
			if (leftNodeStack.size() == 0)
			{
				leftFinished = true;
				break;
			}
			currentLeftNode = leftNodeStack.top();
			leftNodeStack.pop();
			if (currentLeftNode->getRight() != 0)
			{
				currentLeftNode = currentLeftNode->getRight();
				leftNodeStack.push(currentLeftNode);
				break;
			}
		}
	}
	//still some terms left on right
	newNode.appendChild(left);
	newNode.appendChild(right);
	return newNode;
}
示例#17
0
ExpressionNode Addition::addTerms(const ExpressionNode& term1, const ExpressionNode& term2) const
{
	clog << "checkpoint addTerms" << endl;
	
	Number coefficient1;
	Number coefficient2;
	const ExpressionNode * varpart1;
	const ExpressionNode * varpart2;
	ExpressionNode * left;
	ExpressionNode * right;
	ExpressionNode newRight;
	ExpressionNode newCoef;
	ExpressionNode newNode;
	
	if (term1.getType() == NUMBER)
	{
		coefficient1 = term1.getValue();
		varpart1 = 0;
	}
	else if (term1.getType() == OPERATION)
	{
		if (term1.getOperation() == &MULTIPLICATION)
		{
			left = term1.getFirstChild();
			right = left->getRight();
			if (left->getType() == NUMBER)
			{
				coefficient1 = left->getValue();
				varpart1 = right;
			}
			else if (right->getType() == NUMBER)
			{
				coefficient1 = right->getValue();
				varpart1 = left;
			}
			else
			{
				coefficient1 = MULTIPLICATION.getIdentity();
				varpart1 = &term1;
			}
		}
		else
		{
			coefficient1 = MULTIPLICATION.getIdentity();
			varpart1 = &term1;
		}
	}
	else // VARIABLE
	{
		assert(term1.getType() == VARIABLE);
		coefficient1 = MULTIPLICATION.getIdentity();
		varpart1 = &term1;
	}
	
	if (term2.getType() == NUMBER)
	{
		coefficient2 = term2.getValue();
		varpart2 = 0;
	}
	else if (term2.getType() == OPERATION)
	{
		if (term2.getOperation() == &MULTIPLICATION)
		{
			left = term2.getFirstChild();
			right = left->getRight();
			if (left->getType() == NUMBER)
			{
				coefficient2 = left->getValue();
				varpart2 = right;
			}
			else if (right->getType() == NUMBER)
			{
				coefficient2 = right->getValue();
				varpart2 = left;
			}
			else
			{
				coefficient2 = MULTIPLICATION.getIdentity();
				varpart2 = &term2;
			}
		}
		else
		{
			coefficient2 = MULTIPLICATION.getIdentity();
			varpart2 = &term2;
		}
	}
	else // VARIABLE
	{
		assert(term2.getType() == VARIABLE);
		coefficient2 = MULTIPLICATION.getIdentity();
		varpart2 = &term2;
	}
	
	if (varpart1 != 0 && varpart2 != 0)
	{
		if (*varpart1 == *varpart2)
		{
			clog << "addTerms simplify like terms" << endl
				<< "coef1: " << coefficient1 << " var1: " << *varpart1 << endl
				<< "coef2: " << coefficient2 << " var2: " << *varpart2 << endl;
			
			newCoef = ExpressionNode(coefficient1 + coefficient2);
			newRight = *varpart1;
			newNode = ExpressionNode(&MULTIPLICATION);
			newNode.appendChild(newCoef);
			newNode.appendChild(newRight);
			clog << "sum: " << newNode << endl;
			return newNode;
		}
		else
		{
			clog << "*varpart1: " << *varpart1 << " *varpart2: " << endl;
			throw ExpressionNode::GenericError("adding unaddable terms");
		}
	}
	else
	{
		if (varpart1 == 0 && varpart2 == 0)
		{
			clog << "sum: " << coefficient1 + coefficient2 << endl;
			return ExpressionNode(coefficient1 + coefficient2);
		}
		else
		{
			throw ExpressionNode::GenericError("adding unaddable terms");
		}
	}
	throw ExpressionNode::GenericError("reached end of addTerms w/o returning.");
	//if (left.getNodeType() == NUMBER && right.getNodeType() == NUMBER)
	//{
		//ExpressionNode newNode;
		//newNode.setNodeType(NUMBER);
		//newNode.setValue(Number(left.getValue().getInt() + right.getValue().getInt()));
		//return newNode;
	//}
}
示例#18
0
 bool  IsConstant( void ) const {
     return left->IsConstant() && right->IsConstant();
 }
示例#19
0
std::ostream& operator<<(std::ostream& out, const ExpressionNode& node)
{
	ExpressionNode * ptr = 0;
	
	if (node.getType() == OPERATION)
	{
		if (node.getOperation() == 0)
		{
			if (node.getFirstChild() != 0)
			{
				throw ExpressionNode::GenericError("ERROR: inserting OPERATION parent node w/o operation into ostream");
			}
			else
			{
				out << "()";
				return out;
			}		
		}
		if (node.getOperation()->isFuncFormat() == true)
		{
			out << *(node.getOperation()) << "(";
			ptr = node.getFirstChild();
			if (ptr != 0)
			{
				out << *ptr;
				ptr = ptr->getRight();
				while (ptr != 0)
				{
					out << ", " << *ptr;
					ptr = ptr->getRight();
				}
			}
			out << ")";
		}
		else
		{
			out << "(";
			ptr = node.getFirstChild();
			if (ptr != 0)
			{
				out << *ptr;
				ptr = ptr->getRight();
				while (ptr != 0)
				{
					out << *(node.getOperation()) << *ptr;
					ptr = ptr->getRight();
				}
			}
			out << ")";
		}
	}
	else if (node.getType() == VARIABLE)
	{
		if (node.getVariable() == 0)
		{
			throw ExpressionNode::GenericError("ERROR: inserting VARIABLE node w/o variable into ostream");
		}
		out << *(node.getVariable());
	}
	else
	{
		if (node.getType() != NUMBER)
		{
			int i = node.getType();
			std::clog << std::endl << i << std::endl;
		}
		assert(node.getType() == NUMBER);
		out << node.getValue();
	}
	return out;
}
示例#20
0
void Expression::ConvertInfixToPostfix()
{
    if (!m_PostfixExpression.empty() || m_InfixExpression.empty())
        return;

    m_Result = true;
    m_Status = true;

    std::stack<ExpressionNode> stackOperator;
    ExpressionNode::ExpressionNodeType lastType = ExpressionNode::Unknown;
    for (PostfixVector::size_type i = 0; i < m_InfixExpression.size(); ++i)
    {
        ExpressionNode expNode;
        expNode.Initialize(m_InfixExpression[i]);
        const ExpressionNode::ExpressionNodeType type = expNode.GetType();
        if (type == ExpressionNode::Numeric)
        {
            // Operand, add to postfix expression
            m_PostfixExpression.push_back(expNode);
            while (!stackOperator.empty() && stackOperator.top().IsUnaryOperator())
            {
                m_PostfixExpression.push_back(stackOperator.top());
                stackOperator.pop();
            }
        }
        else if (type == ExpressionNode::LParenthesis)
        {
            // Left Parentheses, add to stack
            stackOperator.push(expNode);
        }
        else if (type == ExpressionNode::RParenthesis)
        {
            // Right Parentheses, reverse search the Left Parentheses, add all operator of the middle
            ExpressionNode node;
            while (!stackOperator.empty())
            {
                node = stackOperator.top();
                stackOperator.pop();
                if (node.GetType() == ExpressionNode::LParenthesis)
                {
                    while (!stackOperator.empty() && stackOperator.top().IsUnaryOperator())
                    {
                        m_PostfixExpression.push_back(stackOperator.top());
                        stackOperator.pop();
                    }
                    break;
                }
                else
                    m_PostfixExpression.push_back(node);
            }
            // The lastest node must be Left Parentheses
            if (node.GetType() != ExpressionNode::LParenthesis)
            {
                m_Status = false;
            }
        }
        else
        {
            if (ExpressionNode::IsUnaryNode(type) && (m_PostfixExpression.empty() ||
                                                        (lastType != ExpressionNode::Unknown &&
                                                         lastType != ExpressionNode::RParenthesis &&
                                                         lastType != ExpressionNode::Numeric)))
            {
                expNode.SetUnaryOperator();
                stackOperator.push(expNode);
            }
            else if (stackOperator.empty())
            {
                stackOperator.push(expNode);
            }
            else
            {
                ExpressionNode beforeExpNode = stackOperator.top();
                if (beforeExpNode.GetType() != ExpressionNode::LParenthesis &&
                    beforeExpNode.GetPriority() >= expNode.GetPriority())
                {
                    m_PostfixExpression.push_back(beforeExpNode);
                    stackOperator.pop();
                }

                stackOperator.push(expNode);
            }
        }

        lastType = type;
    }

    while (!stackOperator.empty())
    {
        ExpressionNode beforeExpNode = stackOperator.top();
        if (beforeExpNode.GetType() == ExpressionNode::LParenthesis)
        {
            m_Status = false;
        }
        m_PostfixExpression.push_back(beforeExpNode);
        stackOperator.pop();
    }

#ifdef CC_PARSER_TEST
    wxString infix, postfix;
    for (InfixVector::size_type i = 0; i < m_InfixExpression.size(); ++i)
        infix += m_InfixExpression[i] + _T(" ");
    for (PostfixVector::size_type i = 0; i < m_PostfixExpression.size(); ++i)
        postfix += m_PostfixExpression[i].GetToken() + _T(" ");
    TRACE(_T("ConvertInfixToPostfix() : InfixExpression : %s"),   infix.wx_str());
    TRACE(_T("ConvertInfixToPostfix() : PostfixExpression : %s"), postfix.wx_str());
#endif
}
示例#21
0
 void registerWith(ExpressionNode<T_element>& e) const
 {
   e.registerRequiredBy(*this);
 }
示例#22
0
void ExpressionNode::GenCode(CodeEmitter &e, bool travSib, int virtualRegister, int toff) {
	DeclarationNode *dPtr;
	ExpressionNode *argPtr;
	int localToff, boolSkipLoc, currentLoc, currentReg;
	bool isUnary = true;
	
	// Assign virtual register to 'real' register
	int actualRegister = virtualRegister%MAX_EXP_REGISTERS+FIRST_REG_OFFSET;
	int nextRegister = (virtualRegister+1)%MAX_EXP_REGISTERS+FIRST_REG_OFFSET;

	localToff = toff;
	switch (subKind) {
		case OpK:
			// process left child
			if (child[0] != NULL)
				child[0]->GenCode(e, true, virtualRegister, toff);

			// mark location for short circuit jump
			if (op == "&&" || op == "||")
                boolSkipLoc = e.emitSkip(1);
			
			if (child[1] != NULL) {
				isUnary = false;
				
				// see if all of our registers are full...
				if (virtualRegister+1 >= MAX_EXP_REGISTERS) {
					// push value from "next" register 					
					e.emitRM("ST", nextRegister, toff--, fp, "dump register"); // push 
				}
				else
					e.emitComment("Left side will remain in register");

				/*
				// save left side
				localToff = toff--;
				e.emitRM("ST", ac, localToff, fp, "save left side");
				*/
				
				// process right child
				child[1]->GenCode(e, true, virtualRegister+1, toff);

				/*
				// load left back into the accumulator
				toff = localToff;
				e.emitRM("LD", ac1, localToff, fp, "load left into ac1");
				*/
			}
			
			// process operators
			// arithmetic operators
			if (op == "+")
				e.emitRO("ADD", actualRegister, actualRegister, nextRegister, "op +");
			else if (op == "-" && !isUnary) 
                e.emitRO("SUB", actualRegister, actualRegister, nextRegister, "op -");
			else if (op == "*")
				e.emitRO("MUL", actualRegister, actualRegister, nextRegister, "op *");
			else if (op == "/")
				e.emitRO("DIV", actualRegister, actualRegister, nextRegister, "op /");
			else if (op == "%") {
				e.emitRO("DIV", rt, actualRegister, nextRegister, "begin op %");
				e.emitRO("MUL", nextRegister, rt, nextRegister, "");
				e.emitRO("SUB", actualRegister, actualRegister, nextRegister, "end op %");
			}
			else if (op == "&&") {
				/**** Code for the non short circuit case ****
				e.emitRO("ADD", actualRegister, actualRegister, nextRegister, "prepare for && op");
				e.emitRM("LDC", nextRegister, 2, 0, "load constant for &&");
				e.emitRO("SUB", actualRegister, nextRegister, actualRegister, "compute value");
				e.emitRM("JEQ", actualRegister, 2, pc, "op &&");

				e.emitRM("LDC", actualRegister, 0, 0, "load false into ac");
				e.emitRM("LDA", pc, 1, pc, "jump past true case");
				e.emitRM("LDC", actualRegister, 1, 0, "load true into ac");
				**** Code for the non short circuit case *****/
				
				e.emitRM("JGT", nextRegister, 2, pc, "op && (right side)");
                
				// special case: If left side of && is false then whole expression is false
				currentLoc = e.emitSkip(0);
				e.emitBackup(boolSkipLoc);
				e.emitRMAbs("JEQ", actualRegister, currentLoc, "Skip right child of && if left is false");
				e.emitRestore();

				e.emitRM("LDC", actualRegister, 0, 0, "load false into ac");
				e.emitRM("LDA", pc, 1, pc, "jump past true case");
				e.emitRM("LDC", actualRegister, 1, 0, "load true into ac");				
			}
			else if (op == "||") {
				/**** Code for the non short circuit case ****
				e.emitRO("ADD", actualRegister, actualRegister, nextRegister, "prepare for || op");
				e.emitRM("JGT", actualRegister, 2, pc, "op ||");

				e.emitRM("LDC", actualRegister, 0, 0, "load false into ac");
				e.emitRM("LDA", pc, 1, pc, "jump past true case");
				e.emitRM("LDC", actualRegister, 1, 0, "load true into ac");
				**** Code for the non short circuit case *****/
				
				//e.emitRM("JEQ", nextRegister, 2, pc, "op || (right side)");
				
				/* Since the left side is short circuited the right side alone will determine 
				whether the expression is true or false. Just make sure the RHS is int the right
				register */
				e.emitRM("LDA", actualRegister, 0, nextRegister, "Move RHS to current accumulator");
				
				// special case: If left side of || is true then whole expression is true
				currentLoc = e.emitSkip(0);
				e.emitBackup(boolSkipLoc);
				e.emitRMAbs("JGT", actualRegister, currentLoc, "Skip right child of || if left is true");
				e.emitRestore();

				//e.emitRM("LDC", actualRegister, 1, 0, "load true into ac");
				//e.emitRM("LDA", pc, 1, pc, "jump past false case");
				//e.emitRM("LDC", actualRegister, 0, 0, "load false into ac");			
			}
			else if (op == "!") {
				e.emitRM("JEQ", actualRegister, 2, pc, "op !");
				e.emitRM("LDC", actualRegister, 0, 0, "load false into ac");
				e.emitRM("LDA", pc, 1, pc, "jump past true case");
				e.emitRM("LDC", actualRegister, 1, 0, "load true into ac");
			}
			else if (op == "-" and isUnary) {
				e.emitRM("LDC", rt, 0, 0, "Load zero in rt for unary -");
				e.emitRO("SUB", actualRegister, rt, actualRegister, "op unary -");
			}
			else { // comparison operators
				e.emitRO("SUB", actualRegister, actualRegister, nextRegister, "prepare for comparison op");
				
				if (op == "==") 
					e.emitRM("JEQ", actualRegister, 2, pc, "op ==");
				else if (op == "!=")
					e.emitRM("JNE", actualRegister, 2, pc, "op !=");
				else if (op == "<")
					e.emitRM("JLT", actualRegister, 2, pc, "op <");					
				else if (op == "<=")
					e.emitRM("JLE", actualRegister, 2, pc, "op <=");				
				else if (op == ">")
					e.emitRM("JGT", actualRegister, 2, pc, "op >");
				else if (op == ">=")
					e.emitRM("JGE", actualRegister, 2, pc, "op >=");

				e.emitRM("LDC", actualRegister, 0, 0, "load false into ac");
				e.emitRM("LDA", pc, 1, pc, "jump past true case");
				e.emitRM("LDC", actualRegister, 1, 0, "load true into ac");
			}

			// if we dumped a register earlier we need to restore it here
			if (virtualRegister+1 >= MAX_EXP_REGISTERS) {
				// pop value from stack back into next register 
				e.emitRM("LD", nextRegister, ++toff, fp, "restore register"); // pop
			}			
			break;
		case AssignK:
			// process RHS of assignment
			if (child[1] != NULL)
				child[1]->GenCode(e, true, virtualRegister, toff);

			// call function to store in LHS
			((ExpressionNode *)child[0])->GenAssignLHS(e, virtualRegister, toff);			
			break;

		case ConstK:
			e.emitRM("LDC", actualRegister, val, 0, "load constant");
			break;

		case IdK:
			if (this->dPtr->isArray) {
				// is this array indexed?
				if (child[0] == NULL) {  // must be a parameter
					if (this->dPtr->theScope == TreeNode::Parameter)
						e.emitRM("LD", actualRegister, this->dPtr->offset, (this->dPtr->theScope == TreeNode::Global)?gp:fp, "Load address of base of array " + this->name);
					else
						e.emitRM("LDA", actualRegister, this->dPtr->offset, (this->dPtr->theScope == TreeNode::Global)?gp:fp, "Load address of base of array " + this->name);
				}
				else { 
					child[0]->GenCode(e, true, virtualRegister, toff);
					
					if (this->dPtr->theScope == TreeNode::Parameter)
						e.emitRM("LD", rt, this->dPtr->offset, (this->dPtr->theScope == TreeNode::Global)?gp:fp, "Load address of base of array " + this->name);
					else
						e.emitRM("LDA", rt, this->dPtr->offset, (this->dPtr->theScope == TreeNode::Global)?gp:fp, "Load address of base of array " + this->name);

					e.emitRO("SUB", actualRegister, rt, actualRegister, "index off of the base");
					e.emitRM("LD", actualRegister, 0, actualRegister, "load the value");
				}
			}
			else {
				e.emitRM("LD", actualRegister, this->dPtr->offset, (this->dPtr->theScope == TreeNode::Global)?gp:fp, "load variable " + name);
			}
			break;
		case CallK:
			// dump any used registers to temps before calling a function
			currentReg = actualRegister;
			if (currentReg > FIRST_REG_OFFSET)
				e.emitComment("Need to dump Registers before call");
			
			while (currentReg > FIRST_REG_OFFSET)
				e.emitRM("ST", --currentReg, toff--, fp, "Save register to temporaries");

			dPtr = (DeclarationNode *)symtab->lookup(name.c_str());
			currentLoc = toff--;
			e.emitRM("ST", fp, currentLoc, fp, "Store old fp in ghost frame");

			// leave room for return param
			--toff;

			// process function parameters
			argPtr = (ExpressionNode *)this->child[0];	// set the parameter pointer to the function declaration parameters
			//localToff = toff;
			while (argPtr != NULL) {
				//localToff--;
				//toff--;
				argPtr->GenCode(e, false, 0, toff);
				// store expression result
				e.emitRM("ST", FIRST_REG_OFFSET, toff-- , fp, "Save parameter");
				argPtr = (ExpressionNode *)argPtr->sibling;
			}		

			// prepare for jump
			e.emitRM("LDA", fp, currentLoc, fp, "Load address of new frame");
			e.emitRM("LDA", FIRST_REG_OFFSET, 1, pc, "Put return address in ac");
			e.emitRMAbs("LDA", pc, dPtr->offset, "Call " + dPtr->name);
			
			// save return value
			e.emitRM("LDA", actualRegister, 0, rt, "Save the result in current accumulator");

			// restore temps back to registers
			if (currentReg < actualRegister)
				e.emitComment("Need to restore registers after call");

			toff = currentLoc;
			while (currentReg < actualRegister)
				e.emitRM("LD", currentReg++, ++toff, fp, "Load Register from Temporaries");

			// restore toff
			//toff = localToff;
			break;
	}

	if (sibling != NULL && travSib) {
		e.emitComment(NO_COMMENT);	
		sibling->GenCode(e, true, 0, localToff);
	}
}
示例#23
0
 void unregisterFrom(ExpressionNode<T_element>& e) const
 {
   e.unregisterRequiredBy(*this);
 }
示例#24
0
BuiltinExecutables::BuiltinExecutables(VM& vm)
    : m_vm(vm)
#define INITIALIZE_BUILTIN_SOURCE_MEMBERS(name, functionName, length) , m_##name##Source(makeSource(StringImpl::createFromLiteral(s_##name, length)))
    JSC_FOREACH_BUILTIN_CODE(INITIALIZE_BUILTIN_SOURCE_MEMBERS)
#undef EXPOSE_BUILTIN_STRINGS
{
}

UnlinkedFunctionExecutable* BuiltinExecutables::createDefaultConstructor(ConstructorKind constructorKind, const Identifier& name)
{
    static NeverDestroyed<const String> baseConstructorCode(ASCIILiteral("(function () { })"));
    static NeverDestroyed<const String> derivedConstructorCode(ASCIILiteral("(function () { super(...arguments); })"));

    switch (constructorKind) {
    case ConstructorKind::None:
        break;
    case ConstructorKind::Base:
        return createExecutable(m_vm, makeSource(baseConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);
    case ConstructorKind::Extends:
        return createExecutable(m_vm, makeSource(derivedConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);
    }
    ASSERT_NOT_REACHED();
    return nullptr;
}

UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const SourceCode& code, const Identifier& name, ConstructAbility constructAbility)
{
    return createExecutable(m_vm, code, name, ConstructorKind::None, constructAbility);
}

UnlinkedFunctionExecutable* createBuiltinExecutable(VM& vm, const SourceCode& code, const Identifier& name, ConstructAbility constructAbility)
{
    return BuiltinExecutables::createExecutable(vm, code, name, ConstructorKind::None, constructAbility);
}

UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility)
{
    JSTextPosition positionBeforeLastNewline;
    ParserError error;
    bool isParsingDefaultConstructor = constructorKind != ConstructorKind::None;
    JSParserBuiltinMode builtinMode = isParsingDefaultConstructor ? JSParserBuiltinMode::NotBuiltin : JSParserBuiltinMode::Builtin;
    UnlinkedFunctionKind kind = isParsingDefaultConstructor ? UnlinkedNormalFunction : UnlinkedBuiltinFunction;
    RefPtr<SourceProvider> sourceOverride = isParsingDefaultConstructor ? source.provider() : nullptr;
    std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
        &vm, source, Identifier(), builtinMode,
        JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error,
        &positionBeforeLastNewline, constructorKind);

    if (!program) {
        dataLog("Fatal error compiling builtin function '", name.string(), "': ", error.message());
        CRASH();
    }

    StatementNode* exprStatement = program->singleStatement();
    RELEASE_ASSERT(exprStatement);
    RELEASE_ASSERT(exprStatement->isExprStatement());
    ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
    RELEASE_ASSERT(funcExpr);
    RELEASE_ASSERT(funcExpr->isFuncExprNode());
    FunctionMetadataNode* metadata = static_cast<FuncExprNode*>(funcExpr)->metadata();
    RELEASE_ASSERT(!program->hasCapturedVariables());
    
    metadata->setEndPosition(positionBeforeLastNewline);
    RELEASE_ASSERT(metadata);
    RELEASE_ASSERT(metadata->ident().isNull());
    
    // This function assumes an input string that would result in a single anonymous function expression.
    metadata->setEndPosition(positionBeforeLastNewline);
    RELEASE_ASSERT(metadata);
    metadata->overrideName(name);
    VariableEnvironment dummyTDZVariables;
    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, dummyTDZVariables, DerivedContextType::None, WTFMove(sourceOverride));
    return functionExecutable;
}
示例#25
0
ExpressionNode Addition::simplify(ExpressionNode& left, ExpressionNode& right)
{
	std::clog << "checkpoint addsimplify" << std::endl;
	
	//simplest case: at least one side is just 0
	if (left.getType() == NUMBER && left.getValue().getInt() == 0)
	{
		return right;
	}
	else if (right.getType() == NUMBER && right.getValue().getInt() == 0)
	{
		return left;
	}
	
	// for each left term: for each right term: try adding
	
	std::stack <ExpressionNode*> leftNodeStack;
	ExpressionNode * currentLeftNode = &left;
	bool leftFinished = false;
	std::stack <ExpressionNode*> rightNodeStack;
	ExpressionNode * currentRightNode = &right;
	bool rightFinished = false;
	ExpressionNode * tempNodePtr;
	ExpressionNode newNode;
	
	while (leftFinished == false)
	{
		std::clog << "looping left" << std::endl;
		
		if (currentLeftNode->getType() == OPERATION && currentLeftNode->getOperation() == &ADDITION)
		{
			
			if (currentLeftNode->getFirstChild() == 0)
			{
				throw ExpressionNode::WrongArityError();
			}
			currentLeftNode = currentLeftNode->getFirstChild();
			leftNodeStack.push(currentLeftNode);
			continue;
		}
		
		// leaf term on left tree: traverse right tree
		while (rightFinished == false)
		{
			std::clog << "looping right" << std::endl;
			
			if (currentRightNode->getType() == OPERATION && currentRightNode->getOperation() == &ADDITION)
			{
				if (currentRightNode->getFirstChild() == 0)
				{
					throw ExpressionNode::WrongArityError();
				}
				currentRightNode = currentRightNode->getFirstChild();
				rightNodeStack.push(currentRightNode);
				continue;
			}
			
			std::clog << "checkpoint addsimplify: before isAddable; " << std::endl;
			// leaf terms on both sides: attempt adding
			if (isAddable(*currentLeftNode, *currentRightNode))
			{
				std::clog << "checkpoint addsimplify: after isAddable; " << std::endl;
				std::clog << *currentLeftNode << " " << *currentRightNode << std::endl;
				std::clog << "add testrun: " << addTerms(*currentLeftNode, *currentRightNode);
				(*currentLeftNode).replace( addTerms(*currentLeftNode, *currentRightNode) );
				std::clog << "checkpoint addsimplify: after addTerms; " << std::endl;
				if (currentRightNode == &right)
				{
					//entire right tree has been assimilated
					return left;
				}
				tempNodePtr = currentRightNode;
				currentRightNode = right.findParentOf(*currentRightNode);
				right.remove(*tempNodePtr);
			} 
			while (true)
			{
				if (rightNodeStack.size() == 0)
				{
					rightFinished = true;
					break;
				}
				currentRightNode = rightNodeStack.top();
				rightNodeStack.pop();
				if (currentRightNode->getRight() != 0)
				{
					currentRightNode = currentRightNode->getRight();
					rightNodeStack.push(currentRightNode);
					break;
				}
			}
		}
		while (true)
		{
			if (leftNodeStack.size() == 0)
			{
				leftFinished = true;
				break;
			}
			currentLeftNode = leftNodeStack.top();
			leftNodeStack.pop();
			if (currentLeftNode->getRight() != 0)
			{
				currentLeftNode = currentLeftNode->getRight();
				leftNodeStack.push(currentLeftNode);
				break;
			}
		}
	}
	//still some terms left on right
	left.setRight(&right);
	newNode.init(&ADDITION, &left);
	return newNode;
}