Beispiel #1
0
// ------------------------------------------------------------ Evaluate one operator.
void dispatchEval( Eval ev ) {
  double result;
  Operand rightp = topStack( ev->Ands ); popStack( ev->Ands );
  Operand leftp  = topStack( ev->Ands ); popStack( ev->Ands );
  double right = value( rightp ); freeOperand( rightp );
  double left = value( leftp ); freeOperand( leftp );
  
  Operator op = topStack( ev->Ators); popStack( ev->Ators );  ev->numbin--;
  printf( "  Evaluating: %g%c%g\n", left, symbolOperator( op ), right );
  switch ( symbolOperator( op ) ) {
  case '+': result = left + right; 		break;
  case '-': result = left - right; 		break;
  case '*': result = left * right; 		break;
  case '/': result = left / right; 		break;
  case '%': result = fmod(left, right); 	break;
  case '^': result = pow (left, right); 	break;
  default: result = HUGE_VAL;	/* shouldn't occur */
  }
  freeOperator( op );
  Operand And = newOperand( result );
  pushStack( ev->Ands, And );
}
Beispiel #2
0
		std::string Value::toString() const {
			switch (kind()) {
				case SELF:
					return "self";
				case THIS:
					return "this";
				case CONSTANT:
					return makeString("Constant(%s)", constant().toString().c_str());
				case ALIAS:
					return makeString("Alias(alias: %s, templateArguments: %s)",
					                  alias().toString().c_str(),
					                  makeArrayString(aliasTemplateArguments()).c_str());
				case PREDICATE:
					return makeString("Predicate(%s)", predicate().toString().c_str());
				case LOCALVAR:
					return makeString("LocalVar(%s)", localVar().toString().c_str());
				case REINTERPRET:
					return makeString("Reinterpret(value: %s)", reinterpretOperand().toString().c_str());
				case DEREF_REFERENCE:
					return makeString("DerefReference(%s)", derefOperand().toString().c_str());
				case TERNARY:
					return makeString("Ternary(cond: %s, ifTrue: %s, ifFalse: %s)",
						ternaryCondition().toString().c_str(),
						ternaryIfTrue().toString().c_str(),
						ternaryIfFalse().toString().c_str());
				case CAST:
					return makeString("Cast(value: %s, targetType: %s)",
						castOperand().toString().c_str(),
						castTargetType()->toString().c_str());
				case POLYCAST:
					return makeString("PolyCast(value: %s, targetType: %s)",
						polyCastOperand().toString().c_str(),
						polyCastTargetType()->toString().c_str());
				case INTERNALCONSTRUCT:
					return makeString("InternalConstruct(args: %s)",
						makeArrayString(internalConstructParameters()).c_str());
				case MEMBERACCESS:
					return makeString("MemberAccess(object: %s, var: %s)",
						memberAccessObject().toString().c_str(),
						memberAccessVar().toString().c_str());
				case BIND_REFERENCE:
					return makeString("BindReference(value: %s)", bindReferenceOperand().toString().c_str());
				case TYPEREF:
					return makeString("TypeRef(targetType: %s)", typeRefType()->toString().c_str());
				case TEMPLATEVARREF:
					return makeString("TemplateVarRef(templateVar: %s)", templateVar()->toString().c_str());
				case CALL:
					return makeString("Call(funcValue: %s, args: %s)",
						callValue().toString().c_str(),
						makeArrayString(callParameters()).c_str());
				case FUNCTIONREF:
					return makeString("FunctionRef(name: %s, type: %s, parentType: %s, templateArgs: %s)",
						functionRefFunction().fullName().toString().c_str(),
						type()->toString().c_str(),
						functionRefParentType() != nullptr ?
							functionRefParentType()->toString().c_str() :
							"[NONE]",
						makeArrayString(functionRefTemplateArguments()).c_str());
				case TEMPLATEFUNCTIONREF:
					return makeString("TemplateFunctionRef(name: %s, parentType: %s)",
						templateFunctionRefName().c_str(),
						templateFunctionRefParentType()->toString().c_str());
				case METHODOBJECT:
					return makeString("MethodObject(method: %s, object: %s)",
						methodObject().toString().c_str(),
						methodOwner().toString().c_str());
				case INTERFACEMETHODOBJECT:
					return makeString("InterfaceMethodObject(method: %s, object: %s)",
						interfaceMethodObject().toString().c_str(),
						interfaceMethodOwner().toString().c_str());
				case STATICINTERFACEMETHODOBJECT:
					return makeString("StaticInterfaceMethodObject(method: %s, typeRef: %s)",
						staticInterfaceMethodObject().toString().c_str(),
						staticInterfaceMethodOwner().toString().c_str());
				case CAPABILITYTEST:
					return makeString("CapabilityTest(checkType: %s, capabilityType: %s)",
					                  capabilityTestCheckType()->toString().c_str(),
					                  capabilityTestCapabilityType()->toString().c_str());
				case Value::ARRAYLITERAL:
					return makeString("ArrayLiteral(type: %s, values: %s)",
					                  type()->toString().c_str(),
					                  makeArrayString(arrayLiteralValues()).c_str());
				case NEW:
					return makeString("New(placementArg: %s, operand: %s)",
					                  newPlacementArg().toString().c_str(),
					                  newOperand().toString().c_str());
				case CASTDUMMYOBJECT:
					return makeString("[CAST DUMMY OBJECT (FOR SEMANTIC ANALYSIS)](type: %s)",
						type()->toString().c_str());
			}
			
			locic_unreachable("Unknown value kind.");
		}
Beispiel #3
0
		bool Value::operator==(const Value& value) const {
			if (kind() != value.kind()) {
				return false;
			}
			
			if (type() != value.type()) {
				return false;
			}
			
			switch (value.kind()) {
				case Value::SELF:
					return true;
				case Value::THIS:
					return true;
				case Value::CONSTANT:
					return constant() == value.constant();
				case Value::ALIAS:
					return &(alias()) == &(value.alias()) &&
						aliasTemplateArguments() == value.aliasTemplateArguments();
				case Value::PREDICATE:
					return predicate() == value.predicate();
				case Value::LOCALVAR:
					return &(localVar()) == &(value.localVar());
				case Value::REINTERPRET:
					return reinterpretOperand() == value.reinterpretOperand();
				case Value::DEREF_REFERENCE:
					return derefOperand() == value.derefOperand();
				case Value::TERNARY:
					return ternaryCondition() == value.ternaryCondition() && ternaryIfTrue() == value.ternaryIfTrue() && ternaryIfFalse() == value.ternaryIfFalse();
				case Value::CAST:
					return castTargetType() == value.castTargetType() && castOperand() == value.castOperand();
				case Value::POLYCAST:
					return polyCastTargetType() == value.polyCastTargetType() && polyCastOperand() == value.polyCastOperand();
				case Value::INTERNALCONSTRUCT:
					return internalConstructParameters() == value.internalConstructParameters();
				case Value::MEMBERACCESS:
					return memberAccessObject() == value.memberAccessObject() && &(memberAccessVar()) == &(value.memberAccessVar());
				case Value::BIND_REFERENCE:
					return bindReferenceOperand() == value.bindReferenceOperand();
				case Value::TYPEREF:
					return typeRefType() == value.typeRefType();
				case Value::TEMPLATEVARREF:
					return templateVar() == value.templateVar();
				case Value::CALL:
					return callValue() == value.callValue() && callParameters() == value.callParameters();
				case Value::FUNCTIONREF:
					return functionRefParentType() == value.functionRefParentType() && &(functionRefFunction()) == &(value.functionRefFunction()) &&
						functionRefTemplateArguments() == value.functionRefTemplateArguments();
				case Value::TEMPLATEFUNCTIONREF:
					return templateFunctionRefParentType() == value.templateFunctionRefParentType() && templateFunctionRefName() == value.templateFunctionRefName() &&
						templateFunctionRefFunctionType() == value.templateFunctionRefFunctionType();
				case Value::METHODOBJECT:
					return methodObject() == value.methodObject() && methodOwner() == value.methodOwner();
				case Value::INTERFACEMETHODOBJECT:
					return interfaceMethodObject() == value.interfaceMethodObject() && interfaceMethodOwner() == value.interfaceMethodOwner();
				case Value::STATICINTERFACEMETHODOBJECT:
					return staticInterfaceMethodObject() == value.staticInterfaceMethodObject() && staticInterfaceMethodOwner() == value.staticInterfaceMethodOwner();
				case Value::CAPABILITYTEST:
					return capabilityTestCheckType() == value.capabilityTestCheckType() &&
					       capabilityTestCapabilityType() == value.capabilityTestCapabilityType();
				case Value::ARRAYLITERAL:
					return arrayLiteralValues() == value.arrayLiteralValues();
				case Value::NEW:
					return newPlacementArg() == value.newPlacementArg() &&
					       newOperand() == value.newOperand();
				case Value::CASTDUMMYOBJECT:
					return true;
			}
			
			locic_unreachable("Unknown value kind.");
		}
Beispiel #4
0
		size_t Value::hash() const {
			Hasher hasher;
			hasher.add(kind());
			hasher.add(type());
			
			switch (kind()) {
				case Value::SELF:
					break;
				case Value::THIS:
					break;
				case Value::CONSTANT:
					hasher.add(constant());
					break;
				case Value::ALIAS:
					hasher.add(&(alias()));
					hasher.add(aliasTemplateArguments().size());
					for (const auto& argument: aliasTemplateArguments()) {
						hasher.add(argument);
					}
					break;
				case Value::PREDICATE:
					hasher.add(predicate());
					break;
				case Value::LOCALVAR:
					hasher.add(&(localVar()));
					break;
				case Value::REINTERPRET:
					hasher.add(reinterpretOperand());
					break;
				case Value::DEREF_REFERENCE:
					hasher.add(derefOperand());
					break;
				case Value::TERNARY:
					hasher.add(ternaryCondition());
					hasher.add(ternaryIfTrue());
					hasher.add(ternaryIfFalse());
					break;
				case Value::CAST:
					hasher.add(castTargetType());
					hasher.add(castOperand());
					break;
				case Value::POLYCAST:
					hasher.add(polyCastTargetType());
					hasher.add(polyCastOperand());
					break;
				case Value::INTERNALCONSTRUCT:
					hasher.add(internalConstructParameters().size());
					for (const auto& param: internalConstructParameters()) {
						hasher.add(param);
					}
					break;
				case Value::MEMBERACCESS:
					hasher.add(memberAccessObject());
					hasher.add(&(memberAccessVar()));
					break;
				case Value::BIND_REFERENCE:
					hasher.add(bindReferenceOperand());
					break;
				case Value::TYPEREF:
					hasher.add(typeRefType());
					break;
				case Value::TEMPLATEVARREF:
					hasher.add(templateVar());
					break;
				case Value::CALL:
					hasher.add(callValue());
					hasher.add(callParameters().size());
					for (const auto& param: callParameters()) {
						hasher.add(param);
					}
					break;
				case Value::FUNCTIONREF:
					hasher.add(functionRefParentType());
					hasher.add(&(functionRefFunction()));
					hasher.add(functionRefTemplateArguments().size());
					for (const auto& arg: functionRefTemplateArguments()) {
						hasher.add(arg);
					}
					break;
				case Value::TEMPLATEFUNCTIONREF:
					hasher.add(templateFunctionRefParentType());
					hasher.add(templateFunctionRefName());
					hasher.add(templateFunctionRefFunctionType());
					break;
				case Value::METHODOBJECT:
					hasher.add(methodObject());
					hasher.add(methodOwner());
					break;
				case Value::INTERFACEMETHODOBJECT:
					hasher.add(interfaceMethodObject());
					hasher.add(interfaceMethodOwner());
					break;
				case Value::STATICINTERFACEMETHODOBJECT:
					hasher.add(staticInterfaceMethodObject());
					hasher.add(staticInterfaceMethodOwner());
					break;
				case Value::CAPABILITYTEST:
					hasher.add(capabilityTestCheckType());
					hasher.add(capabilityTestCapabilityType());
					break;
				case Value::ARRAYLITERAL:
					hasher.add(arrayLiteralValues().size());
					for (const auto& value: arrayLiteralValues()) {
						hasher.add(value);
					}
					break;
				case Value::NEW:
					hasher.add(newPlacementArg());
					hasher.add(newOperand());
					break;
				case Value::CASTDUMMYOBJECT:
					break;
			}
			
			return hasher.get();
		}
Beispiel #5
0
		std::string Value::toDiagString() const {
			switch (kind()) {
				case SELF:
					return "self";
				case THIS:
					return "this";
				case CONSTANT:
					return constant().toString();
				case ALIAS:
					return alias().toString();
				case PREDICATE:
					return predicate().toString();
				case LOCALVAR:
					return localVar().name().asStdString();
				case REINTERPRET:
					return reinterpretOperand().toDiagString();
				case DEREF_REFERENCE:
					return makeString("<deref> %s", derefOperand().toDiagString().c_str());
				case TERNARY:
					return makeString("%s ? %s : %s",
						ternaryCondition().toDiagString().c_str(),
						ternaryIfTrue().toDiagString().c_str(),
						ternaryIfFalse().toDiagString().c_str());
				case CAST:
					return castOperand().toDiagString();
				case POLYCAST:
					return polyCastOperand().toDiagString();
				case INTERNALCONSTRUCT:
					return makeString("@(%s)",
						makeArrayString(internalConstructParameters()).c_str());
				case MEMBERACCESS:
					return makeString("%s.%s",
						memberAccessObject().toDiagString().c_str(),
						memberAccessVar().name().c_str());
				case BIND_REFERENCE:
					return makeString("<bind> %s", bindReferenceOperand().toDiagString().c_str());
				case TYPEREF:
					return typeRefType()->toDiagString();
				case TEMPLATEVARREF:
					return templateVar()->fullName().last().asStdString();
				case CALL:
					return makeString("%s(%s)", callValue().toDiagString().c_str(),
						makeArrayString(callParameters()).c_str());
				case FUNCTIONREF:
					return functionRefFunction().fullName().toString();
				case TEMPLATEFUNCTIONREF:
					return makeString("%s::%s",
					                  templateFunctionRefParentType()->toDiagString().c_str(),
					                  templateFunctionRefName().c_str());
				case METHODOBJECT:
					return makeString("%s.%s",
					                  methodOwner().toDiagString().c_str(),
					                  methodObject().toDiagString().c_str());
				case INTERFACEMETHODOBJECT:
					return makeString("%s.%s",
					                  interfaceMethodOwner().toDiagString().c_str(),
					                  interfaceMethodObject().toDiagString().c_str());
				case STATICINTERFACEMETHODOBJECT:
					return makeString("%s.%s",
					                  staticInterfaceMethodOwner().toDiagString().c_str(),
					                  staticInterfaceMethodObject().toDiagString().c_str());
				case CAPABILITYTEST:
					return makeString("%s : %s",
					                  capabilityTestCheckType()->toDiagString().c_str(),
					                  capabilityTestCapabilityType()->toDiagString().c_str());
				case Value::ARRAYLITERAL:
					return makeString("{ %s }", makeArrayString(arrayLiteralValues()).c_str());
				case NEW:
					return makeString("new(%s) %s", newPlacementArg().toDiagString().c_str(),
					                  newOperand().toDiagString().c_str());
				case CASTDUMMYOBJECT:
					locic_unreachable("Shouldn't reach CASTDUMMYOBJECT.");
			}
			
			locic_unreachable("Unknown value kind.");
		}
void newOperandOrFunctionCall(int index) {
    
    // Retrieve symbol
    SymbolTableRow* functionSymbol = getSymbol(index, symbolTableStack->integer);
    
    // Determine if it is a function call or a variable
    if (functionSymbol->category == scVariable || functionSymbol->category == scParameter) newOperand(opdtVariable, index);
    else newFunctionOperator(index);
    
}
Beispiel #7
0
//------------------------------------------------ Read input and evaluate expression.
double evaluateEval(Eval ev) {
	Intype next; // Classification of next input character.
	char inSymbol; // Read input operators into this.
	Operator inOp; // Operator object constructed from inSymbol.
	double inNumVal; // Read input operands into this.
	Operand And; // Operand value
	int numread;
	int n;

	for (;;) {
		next = classifyEval(ev);
		switch (next) {
		case number:
			n = sscanf(ev->instream, "%lg%n", &inNumVal, &numread);
			ev->instream += numread;
			if (n!=1 || sizeStack(ev->Ands) != ev->numbin)
				return expErrorEval(ev);
			And = newOperand(inNumVal);
			pushStack(ev->Ands, And);
			break;

		case op:
			if (sizeStack(ev->Ands) != ev->numbin+1)
				return expErrorEval(ev);
			inSymbol = *(ev->instream++);
			inOp = newOperator(inSymbol);
			forceEval(ev, precedenceOperator(inOp) );
			pushStack(ev->Ators, inOp);
			ev->numbin++;
			break;

		case lpar:
			if (sizeStack(ev->Ands) != ev->numbin) return expErrorEval(ev);
			inSymbol = *(ev->instream++);
			inOp = newOperator(inSymbol); // put left paren on Ators stack
			pushStack(ev->Ators, inOp);
			break;
			
		case rpar:
			n = sscanf(ev->instream, " %c%n", &inSymbol, &numread);
			ev->instream += numread;
			if (sizeStack(ev->Ands) != ev->numbin+1)
				return expErrorEval(ev);
			forceEval(ev, 0);
			if (isemptyStack(ev->Ators))	expErrorEval(ev); // too many right parens
			Operator op = topStack(ev->Ators);         // remove left paren operator from Ators stack
			freeOperator(op);
			popStack(ev->Ators);
			break;

		case end:
			if (sizeStack(ev->Ands) != ev->numbin+1)
				return expErrorEval(ev);
			forceEval(ev, 0);
			if (!isemptyStack(ev->Ators)) return expErrorEval(ev);
			And = topStack(ev->Ands);
			popStack(ev->Ands);
			double retval = value(And);
			freeOperand(And);
			return retval;
			break;

		case bad:
		default:
			return expErrorEval(ev);
		}
	}
}