Example #1
0
llvm::Value* MemberAccess::getPointer(Context &context) {
	if (isStatic) {
		// find class
		Class *cls = targetClass->getClass(context);
		if (!cls)
			throw SymbolNotFound("No such class '" + targetClass->getName() + "'");
		if (cls->getMangleName()[0] == 'J')
			throw InvalidType("'" + cls->getFullName() + "' is an interface");
		// find symbol
		Symbol *symbol = cls->findSymbol(identifier->getName());
		if (!symbol)
			throw SymbolNotFound("No such static member '" + identifier->getName() + "' in class '" + cls->getFullName() + "'");
		if (symbol->type != Symbol::STATIC_MEMBER_VAR)
			throw InvalidType("'" + identifier->getName() + "' in '" + targetClass->getName() + "' is not a static member variable");
		// check permission
		if (symbol->data.identifier.isPrivate && cls != context.currentClass)
			throw CompileException("'" + identifier->getName() + "' is private");
		if (symbol->data.identifier.isProtected && !Class::isA(context.currentClass, cls))
			throw CompileException("'" + identifier->getName() + "' is protected");
		return symbol->data.identifier.value;
	} else {
		// find class
		if (!target->getType(context)->isObject())
			throw InvalidType(std::string("Access member of a ") + target->getType(context)->getName());
		Class *cls = target->getType(context)->getClass();
		// find symbol
		Symbol *symbol = cls->findSymbol(identifier->getName());
		if (!symbol)
			throw SymbolNotFound(std::string("No such member variable in class ") + cls->getName());
		if (symbol->type != Symbol::MEMBER_VAR)
			throw InvalidType("'" + identifier->getName() + "' in '" + targetClass->getName() + "' is not a member variable");
		// check permission
		if (symbol->data.identifier.isPrivate && cls != context.currentClass)
			throw CompileException("'" + identifier->getName() + "' is private");
		if (symbol->data.identifier.isProtected && !Class::isA(context.currentClass, cls))
			throw CompileException("'" + identifier->getName() + "' is protected");
		return addDebugLoc(
				context,
				context.getBuilder().CreateStructGEP(
						nullptr,
						target->load(context),
						symbol->data.member.index),
				loc);
	}
}
Example #2
0
Type* MemberAccess::getType(Context &context) {
	if (isStatic) {
		Class *cls = targetClass->getClass(context);
		if (!cls)
			throw SymbolNotFound("No such class '" + targetClass->getName() + "'");
		if (cls->getMangleName()[0] == 'J')
			throw InvalidType("'" + cls->getFullName() + "' is an interface");
		Symbol *symbol = cls->findSymbol(identifier->getName());
		if (!symbol)
			throw SymbolNotFound("No such static member '" + identifier->getName() + "' in class '" + cls->getFullName() + "'");
		return symbol->data.identifier.type;
	} else {
		if (!target->getType(context)->isObject())
			throw InvalidType(std::string("Access member of a ") + target->getType(context)->getName());
		Class *cls = target->getType(context)->getClass();
		Symbol *symbol = cls->findSymbol(identifier->getName());
		if (!symbol)
			throw SymbolNotFound(std::string("No such member variable in class ") + cls->getName());
		return symbol->data.member.type;
	}
}
Example #3
0
JValue::ObjectIterator::ObjectIterator(jvalue_ref parent)
	: _parent(0)
	, _at_end(false)
{
	_key_value.key = 0;
	_key_value.value = 0;

	if (UNLIKELY(!jobject_iter_init(&_it, parent)))
		throw InvalidType("Can't iterate over non-object");

	_parent = jvalue_copy(parent);
	_at_end = !jobject_iter_next(&_it, &_key_value);
}
Example #4
0
Attribute::Attribute(std::string n, int in) throw (InvalidType, EmptyName){
	while(!n.empty()) //strip space
	{
		if(n.at(0) == ' ')
			n.erase(0,0);
		else
			break;
	}
	if(n.empty()) throw EmptyName();
	name=n;
	
	if( in > 5 || in < 0) throw InvalidType();
	ident=in;
 	}	 
Example #5
0
void PathHandler::isRegularFile() const {
  if (exists(path_)) {
    if (!is_regular_file(path_)) {
      if (is_directory(path_)) {
        throw InvalidType(std::string("Error in ") +
          "\"PathHandler::isRegularFile\":\n  " +
          path_.generic_string() +
          "\n  is a directory, not a file.");
      }
      else {
        throw InvalidType(std::string("Error in ") +
          "\"PathHandler::isRegularFile\":\n  " +
          path_.generic_string() +
          "\n  exists but it is neither a regular file nor a directory.");
      }
    }
  }
  else {
    throw NonExistent(std::string("Error in ") +
      "\"PathHandler::isRegularFile\":\n  " +
      path_.generic_string() +
      "\n  does not exist.");
  }
}
Example #6
0
void PathHandler::isRootFilename() const {
  if (is_directory(path_)) {
    throw InvalidType(std::string("Error in ") +
      "\"PathHandler::isRootFilename\":\n  " +
      path_.generic_string() +
      "\n  is a directory, not a root filename.");
  }
  else {
    if (!is_directory(path_.parent_path())) {
      throw NonExistent(std::string("Error in ") +
        "\"PathHandler::isRootFilename\":\n  " +
        "The parent path of the output root filename is\n  " +
        path_.parent_path().generic_string() +
        "\n  This is not an existing directory.");
    }
  }
}
Example #7
0
Type* FunctionCall::getType(Context &context) {
	Symbol *symbol = NULL;
	if (target)
		symbol = target->getType(context)->getClass()->findSymbol(identifier->getName());
	else if (identifier->getName().rfind("::") != std::string::npos) {
		Class *targetClass = context.findClass(identifier->getName().substr(0, identifier->getName().rfind("::")));
		if (!targetClass)
			throw SymbolNotFound(identifier->getName().substr(0, identifier->getName().rfind("::")));
		symbol = targetClass->findSymbol(identifier->getName().substr(identifier->getName().rfind("::") + 2));
	} else
		symbol = context.currentClass->findSymbol(identifier->getName());
	if (!symbol)
		throw SymbolNotFound(identifier->getName());
	switch (symbol->type) {
	case Symbol::STATIC_FUNCTION:
		return symbol->data.static_function.function->getReturnType();
	case Symbol::FUNCTION:
		return symbol->data.function.function->getReturnType();
	default:
		throw InvalidType("calling a symbol which is not a function");
	}
}
Example #8
0
llvm::Value* FunctionCall::load(Context &context) {
	std::vector<Type*> actual_type;
	for (std::list<Expression*>::iterator it = arg_list.begin(); it != arg_list.end(); it++)
		actual_type.push_back((*it)->getType(context));

	Symbol *symbol = NULL;
	Class *targetClass = NULL;
	if (target == NULL) {
		// static call or self call
		if (identifier->getName().rfind("::") != std::string::npos) {
			// static call

			// find class
			targetClass = context.findClass(identifier->getName().substr(0, identifier->getName().rfind("::")));
			if (!targetClass)
				throw SymbolNotFound("Class '" + identifier->getName().substr(0, identifier->getName().rfind("::")) + "'");

			// find function
			symbol = targetClass->findSymbol(identifier->getName().substr(identifier->getName().rfind("::") + 2));
			if (!symbol)
				throw SymbolNotFound("Function '" + identifier->getName() + "'");

			// match the best override
			symbol = bestMatch(symbol, actual_type, context);
			if (!symbol)
				throw SymbolNotFound("No matching call for '" + Function::genName(identifier->getName(), actual_type) + "'");

			// check symbol is static function
			if (symbol->type != Symbol::STATIC_FUNCTION)
				throw InvalidType("'" + symbol->data.function.function->getName() + "' is not a static function");

			// check symbol's permission
			if (symbol->data.static_function.isPrivate && targetClass != context.currentClass)
				throw CompileException("function '" + symbol->data.static_function.function->getName() + "' is private");
			if (symbol->data.static_function.isProtected && !Class::isA(context.currentClass, targetClass))
				throw CompileException("function '" + symbol->data.static_function.function->getName() + "' is protected");
		} else {
			// self call
			targetClass = context.currentClass;

			// find function
			symbol = targetClass->findSymbol(identifier->getName());
			if (!symbol)
				throw SymbolNotFound("'" + identifier->getName() + "'");

			symbol = bestMatch(symbol, actual_type, context);
			if (!symbol)
				throw SymbolNotFound("No matching call for '" + Function::genName(identifier->getName(), actual_type) + "'");
		}
	} else {
		// member function call
		targetClass = target->getType(context)->getClass();
		
		// find function
		symbol = targetClass->findSymbol(identifier->getName());
		if (!symbol)
			throw SymbolNotFound("Function '" + identifier->getName() + "'");

		symbol = bestMatch(symbol, actual_type, context);
		if (!symbol)
			throw SymbolNotFound("No matching call for '" + Function::genName(identifier->getName(), actual_type) + "'");

		// check symbol is normal function
		if (symbol->type != Symbol::FUNCTION)
			throw InvalidType("function '" + symbol->data.static_function.function->getName() + "' is not a member function");

		// check symbol's permission
		if (symbol->data.static_function.isPrivate && targetClass != context.currentClass)
			throw CompileException("function '" + symbol->data.static_function.function->getName() + "' is private");
		if (symbol->data.static_function.isProtected && !Class::isA(context.currentClass, targetClass))
			throw CompileException("function '" + symbol->data.static_function.function->getName() + "' is protected");
	}

	llvm::Value *function;
	std::vector<llvm::Value*> arg_code;
	switch (symbol->type) {
	case Symbol::FUNCTION: {
		Expression *tmpTarget = target ? target : new Identifier("this");
		if (!tmpTarget->getType(context)->isObject())
			throw InvalidType(std::string("calling a function of ") + tmpTarget->getType(context)->getName());
		llvm::Value *thisval = tmpTarget->load(context);
		if (!target)
			delete tmpTarget;

		if (targetClass->getMangleName()[0] == 'J') {
			// locate vtable
			function = addDebugLoc(
					context,
					context.getBuilder().CreateLoad(
							thisval
					),
					loc
			);
			// for interface call, we have to recalculate the object base address
			// load offset from vtable
			llvm::Value *baseOffset = addDebugLoc(
					context,
					context.getBuilder().CreateLoad(
							addDebugLoc(
									context,
									context.getBuilder().CreateStructGEP(
											nullptr,
											function,
											0
									),
									loc
							)
					),
					loc
			);
			// calculate the base address
			thisval = addDebugLoc(
					context,
					context.getBuilder().CreateIntToPtr(
							addDebugLoc(
									context,
									context.getBuilder().CreateSub(
											addDebugLoc(
													context,
													context.getBuilder().CreatePtrToInt(
															thisval,
															context.getBuilder().getInt32Ty()
													),
													loc
											),
											baseOffset
									),
									loc
							),
							context.getBuilder().getInt8PtrTy(0)
					),
					loc
			);
		} else {
			// locate vtable
			function = addDebugLoc(
					context,
					context.getBuilder().CreateLoad(
							addDebugLoc(
									context,
									context.getBuilder().CreateStructGEP(
											nullptr,
											thisval,
											symbol->data.function.vtableOffset
									),
									loc
							)
					),
					loc
			);

			// for object call, we only need type cast
			thisval = context.getBuilder().CreatePointerCast(
					thisval,
					context.getBuilder().getInt8PtrTy(0)
			);
		}
		// add thisval as the first argument
		arg_code.push_back(thisval);
		// load function pointer from vtable
		function = addDebugLoc(
				context,
				context.getBuilder().CreateLoad(
						addDebugLoc(
								context,
								context.getBuilder().CreateStructGEP(
										nullptr,
										function,
										symbol->data.function.funcPtrOffset
								),
								loc
						)
				),
				loc
		);
		break; }
	case Symbol::STATIC_FUNCTION:
		function = symbol->data.static_function.function->getLLVMFunction(context);
		if (target)
			throw CompileException("Calling a static function of an object");
		break;
	default:
		throw InvalidType("calling a symbol which is not a function");
	}

	// load remaining arguments
	{
		Function *func = symbol->type == Symbol::FUNCTION ? symbol->data.function.function : symbol->data.static_function.function;
		Function::arg_iterator it2 = func->arg_begin();
		for (std::list<Expression*>::iterator it = arg_list.begin(); it != arg_list.end(); it++, it2++)
			arg_code.push_back(Type::cast(context, (*it)->getType(context), (*it)->load(context), it2->first));
	}

	// do the call
	llvm::Value *ans = addDebugLoc(
			context,
			context.getBuilder().CreateCall(function, llvm::ArrayRef<llvm::Value*>(arg_code)),
			loc);
	return ans;
}
Example #9
0
llvm::Value* Op2::load(Context &context) {
	if (op == ASSIGN) {
		llvm::Value *tmp = right->load(context);
		tmp = Type::cast(context, right->getType(context), tmp, left->getType(context));
		addDebugLoc(
				context,
				left->store(context, tmp),
				loc);
		return tmp;
	}
	Type *ansType = Type::higherType(left->getType(context), right->getType(context));
	llvm::Value *lhs = Type::cast(context, left->getType(context), left->load(context), ansType);
	llvm::Value *rhs = Type::cast(context, right->getType(context), right->load(context), ansType);

	// pre type check
	switch (op) {
	case ADD:
	case ADD_ASSIGN:
	case SUB:
	case SUB_ASSIGN:
	case MUL:
	case MUL_ASSIGN:
	case DIV:
	case DIV_ASSIGN:
	case PWR:
	case PWR_ASSIGN:
	case MOD:
	case MOD_ASSIGN:
	case LT:
	case GT:
	case LEQ:
	case GEQ:
	case EQ:
	case NEQ:
		if (!ansType->isNumber() && !ansType->isString())
			throw InvalidType(std::string("can't apply operator ") + OpNames[op] + " to " + left->getType(context)->getName() + " and " + right->getType(context)->getName());
		break;
	case LSH:
	case LSH_ASSIGN:
	case RSH:
	case RSH_ASSIGN:
	case BIT_OR:
	case BIT_OR_ASSIGN:
	case BIT_AND:
	case BIT_AND_ASSIGN:
	case BIT_XOR:
	case BIT_XOR_ASSIGN:
		if (!ansType->isInt())
			throw InvalidType(std::string("can't apply operator ") + OpNames[op] + " to " + left->getType(context)->getName() + " and " + right->getType(context)->getName());
		break;
	case LOG_OR:
	case LOG_OR_ASSIGN:
	case LOG_AND:
	case LOG_AND_ASSIGN:
	case LOG_XOR:
	case LOG_XOR_ASSIGN:
		if (!ansType->isBool())
			throw InvalidType(std::string("can't apply operator ") + OpNames[op] + " to " + left->getType(context)->getName() + " and " + right->getType(context)->getName());
		break;
	case ASSIGN:
		// this has been handled before
		break;
	}

	switch (op) {
	case ADD_ASSIGN:
	case ADD: {
		llvm::Value *tmp;
		if (ansType->isFloat())
			tmp = addDebugLoc(context, context.getBuilder().CreateFAdd(lhs, rhs), loc);
		else
			tmp = addDebugLoc(context, context.getBuilder().CreateAdd(lhs, rhs), loc);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case SUB_ASSIGN:
	case SUB: {
		llvm::Value *tmp;
		if (ansType->isFloat())
			tmp = addDebugLoc(context, context.getBuilder().CreateFSub(lhs, rhs), loc);
		else
			tmp = addDebugLoc(context, context.getBuilder().CreateSub(lhs, rhs), loc);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case MUL_ASSIGN:
	case MUL: {
		llvm::Value *tmp;
		if (ansType->isFloat())
			tmp = addDebugLoc(context, context.getBuilder().CreateFMul(lhs, rhs), loc);
		else
			tmp = addDebugLoc(context, context.getBuilder().CreateMul(lhs, rhs), loc);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case DIV_ASSIGN:
	case DIV: {
		llvm::Value *tmp;
		if (ansType->isFloat())
			tmp = addDebugLoc(context, context.getBuilder().CreateFDiv(lhs, rhs), loc);
		else if (ansType->isUnsigned)
			tmp = addDebugLoc(context, context.getBuilder().CreateUDiv(lhs, rhs), loc);
		else
			tmp = addDebugLoc(context, context.getBuilder().CreateSDiv(lhs, rhs), loc);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case MOD_ASSIGN:
	case MOD: {
		llvm::Value *tmp;
		if (ansType->isUnsigned)
			tmp = addDebugLoc(context, context.getBuilder().CreateURem(lhs, rhs), loc);
		else
			tmp = addDebugLoc(context, context.getBuilder().CreateSRem(lhs, rhs), loc);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case LSH_ASSIGN:
	case LSH: {
		llvm::Value *tmp = addDebugLoc(context, context.getBuilder().CreateShl(lhs, rhs), loc);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case RSH_ASSIGN:
	case RSH: {
		llvm::Value *tmp;
		if (ansType->isUnsigned)
			tmp = addDebugLoc(context, context.getBuilder().CreateLShr(lhs, rhs), loc);
		else
			tmp = addDebugLoc(context, context.getBuilder().CreateAShr(lhs, rhs), loc);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case LT:
		if (ansType->isFloat())
			return addDebugLoc(context, context.getBuilder().CreateFCmpOLT(lhs, rhs), loc);
		else if (ansType->isInt()) {
			if (ansType->isUnsigned)
				return addDebugLoc(context, context.getBuilder().CreateICmpULT(lhs, rhs), loc);
			else
				return addDebugLoc(context, context.getBuilder().CreateICmpSLT(lhs, rhs), loc);
		} else if (ansType->isString())
			throw NotImplemented("comparison of string");
		break;
	case LEQ:
		if (ansType->isFloat())
			return addDebugLoc(context, context.getBuilder().CreateFCmpOLE(lhs, rhs), loc);
		else if (ansType->isInt()) {
			if (ansType->isUnsigned)
				return addDebugLoc(context, context.getBuilder().CreateICmpULE(lhs, rhs), loc);
			else
				return addDebugLoc(context, context.getBuilder().CreateICmpSLE(lhs, rhs), loc);
		} else if (ansType->isString())
			throw NotImplemented("comparison of string");
		break;
	case GT:
		if (ansType->isFloat())
			return addDebugLoc(context, context.getBuilder().CreateFCmpOGT(lhs, rhs), loc);
		else if (ansType->isInt()) {
			if (ansType->isUnsigned)
				return addDebugLoc(context, context.getBuilder().CreateICmpUGT(lhs, rhs), loc);
			else
				return addDebugLoc(context, context.getBuilder().CreateICmpSGT(lhs, rhs), loc);
		} else if (ansType->isString())
			throw NotImplemented("comparison of string");
		break;
	case GEQ:
		if (ansType->isFloat())
			return addDebugLoc(context, context.getBuilder().CreateFCmpOGE(lhs, rhs), loc);
		else if (ansType->isInt()) {
			if (ansType->isUnsigned)
				return addDebugLoc(context, context.getBuilder().CreateICmpUGE(lhs, rhs), loc);
			else
				return addDebugLoc(context, context.getBuilder().CreateICmpSGE(lhs, rhs), loc);
		} else if (ansType->isString())
			throw NotImplemented("comparison of string");
		break;
	case ASSIGN:
		// this has been handled before
		break;
	case EQ:
		if (ansType->isFloat())
			return addDebugLoc(context, context.getBuilder().CreateFCmpOEQ(lhs, rhs), loc);
		else if (ansType->isInt())
			return addDebugLoc(context, context.getBuilder().CreateICmpEQ(lhs, rhs), loc);
		else if (ansType->isString())
			throw NotImplemented("comparison of string");
		break;
	case NEQ:
		if (ansType->isFloat())
			return addDebugLoc(context, context.getBuilder().CreateFCmpONE(lhs, rhs), loc);
		else if (ansType->isInt())
			return addDebugLoc(context, context.getBuilder().CreateICmpNE(lhs, rhs), loc);
		else if (ansType->isString())
			throw NotImplemented("comparison of string");
		break;
	case LOG_AND_ASSIGN:
	case BIT_AND_ASSIGN:
	case LOG_AND:
	case BIT_AND: {
		llvm::Value *tmp = context.getBuilder().CreateAnd(lhs, rhs);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case LOG_OR_ASSIGN:
	case BIT_OR_ASSIGN:
	case LOG_OR:
	case BIT_OR: {
		llvm::Value *tmp = context.getBuilder().CreateOr(lhs, rhs);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case LOG_XOR_ASSIGN:
	case BIT_XOR_ASSIGN:
	case LOG_XOR:
	case BIT_XOR: {
		llvm::Value *tmp = context.getBuilder().CreateXor(lhs, rhs);
		if (hasAssign(op)) {
			tmp = Type::cast(context, ansType, tmp, left->getType(context));
			addDebugLoc(
					context,
					left->store(context, tmp),
					loc);
		}
		return tmp; }
	case PWR:
	case PWR_ASSIGN:
		throw NotImplemented(std::string("operator '") + OpNames[op] + "'");
	}
	throw CompileException("Shouldn't reach here");
}
Example #10
0
Expression::Constant Op2::loadConstant() {
	Type* higherType = Type::higherType(left->getTypeConstant(), right->getTypeConstant());
	Expression::Constant ans;
	switch (op) {
	case ADD_ASSIGN:
	case SUB_ASSIGN:
	case MUL_ASSIGN:
	case DIV_ASSIGN:
	case MOD_ASSIGN:
	case PWR_ASSIGN:
	case BIT_OR_ASSIGN:
	case BIT_AND_ASSIGN:
	case BIT_XOR_ASSIGN:
	case LOG_OR_ASSIGN:
	case LOG_AND_ASSIGN:
	case LOG_XOR_ASSIGN:
	case LSH_ASSIGN:
	case RSH_ASSIGN:
		throw InvalidType(std::string("can't apply operator ") + OpNames[op] + " to constant");
	default:
		break;
	}
	if (higherType->isInt())
		if (higherType->isUnsigned)
			switch (op) {
			case ADD:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._uint64 += right->loadConstant()._uint64;
				else
					ans._uint64 += right->loadConstant()._int64;
				return ans;
			case SUB:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._uint64 -= right->loadConstant()._uint64;
				else
					ans._uint64 -= right->loadConstant()._int64;
				return ans;
			case MUL:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._uint64 *= right->loadConstant()._uint64;
				else
					ans._uint64 *= right->loadConstant()._int64;
				return ans;
			case DIV:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._uint64 /= right->loadConstant()._uint64;
				else
					ans._uint64 /= right->loadConstant()._int64;
				return ans;
			case MOD:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._uint64 %= right->loadConstant()._uint64;
				else
					ans._uint64 %= right->loadConstant()._int64;
				return ans;
			case PWR:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._uint64 = pow(ans._uint64, right->loadConstant()._uint64);
				else
					ans._uint64 = pow(ans._uint64, right->loadConstant()._int64);
				return ans;
			case LT:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._uint64 < right->loadConstant()._uint64;
				else
					ans._bool = ans._uint64 < right->loadConstant()._int64;
				return ans;
			case LEQ:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._uint64 <= right->loadConstant()._uint64;
				else
					ans._bool = ans._uint64 <= right->loadConstant()._int64;
				return ans;
			case GT:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._uint64 > right->loadConstant()._uint64;
				else
					ans._bool = ans._uint64 > right->loadConstant()._int64;
				return ans;
			case GEQ:
				if (left->getTypeConstant()->isUnsigned)
					ans._uint64 = left->loadConstant()._uint64;
				else
					ans._uint64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._uint64 >= right->loadConstant()._uint64;
				else
					ans._bool = ans._uint64 >= right->loadConstant()._int64;
				return ans;
			default:
				throw NotImplemented(std::string("operator ") + OpNames[op] + " not implemented");
			}
		else
			switch (op) {
			case ADD:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._int64 += right->loadConstant()._uint64;
				else
					ans._int64 += right->loadConstant()._int64;
				return ans;
			case SUB:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._int64 -= right->loadConstant()._uint64;
				else
					ans._int64 -= right->loadConstant()._int64;
				return ans;
			case MUL:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._int64 *= right->loadConstant()._uint64;
				else
					ans._int64 *= right->loadConstant()._int64;
				return ans;
			case DIV:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._int64 /= right->loadConstant()._uint64;
				else
					ans._int64 /= right->loadConstant()._int64;
				return ans;
			case MOD:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._int64 %= right->loadConstant()._uint64;
				else
					ans._int64 %= right->loadConstant()._int64;
				return ans;
			case PWR:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._int64 = pow(ans._int64, right->loadConstant()._uint64);
				else
					ans._int64 = pow(ans._int64, right->loadConstant()._int64);
				return ans;
			case LT:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._int64 < right->loadConstant()._uint64;
				else
					ans._bool = ans._int64 < right->loadConstant()._int64;
				return ans;
			case LEQ:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._int64 <= right->loadConstant()._uint64;
				else
					ans._bool = ans._int64 <= right->loadConstant()._int64;
				return ans;
			case GT:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._int64 > right->loadConstant()._uint64;
				else
					ans._bool = ans._int64 > right->loadConstant()._int64;
				return ans;
			case GEQ:
				if (left->getTypeConstant()->isUnsigned)
					ans._int64 = left->loadConstant()._uint64;
				else
					ans._int64 = left->loadConstant()._int64;
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._int64 >= right->loadConstant()._uint64;
				else
					ans._bool = ans._int64 >= right->loadConstant()._int64;
				return ans;
			default:
				throw NotImplemented(std::string("operator ") + OpNames[op] + " not implemented");
			}
	else if (higherType->isFloat())
		switch (op) {
		case ADD:
			if (left->getTypeConstant()->isInt())
				if (left->getTypeConstant()->isUnsigned)
					ans._double = left->loadConstant()._uint64;
				else
					ans._double = left->loadConstant()._int64;
			else
				ans._double = left->loadConstant()._double;
			if (right->getTypeConstant()->isFloat())
				if (right->getTypeConstant()->isUnsigned)
					ans._double += right->loadConstant()._uint64;
				else
					ans._double += right->loadConstant()._int64;
			else
				ans._double += right->loadConstant()._double;
			return ans;
		case SUB:
			if (left->getTypeConstant()->isInt())
				if (left->getTypeConstant()->isUnsigned)
					ans._double = left->loadConstant()._uint64;
				else
					ans._double = left->loadConstant()._int64;
			else
				ans._double = left->loadConstant()._double;
			if (right->getTypeConstant()->isFloat())
				if (right->getTypeConstant()->isUnsigned)
					ans._double -= right->loadConstant()._uint64;
				else
					ans._double -= right->loadConstant()._int64;
			else
				ans._double -= right->loadConstant()._double;
			return ans;
		case MUL:
			if (left->getTypeConstant()->isInt())
				if (left->getTypeConstant()->isUnsigned)
					ans._double = left->loadConstant()._uint64;
				else
					ans._double = left->loadConstant()._int64;
			else
				ans._double = left->loadConstant()._double;
			if (right->getTypeConstant()->isFloat())
				if (right->getTypeConstant()->isUnsigned)
					ans._double *= right->loadConstant()._uint64;
				else
					ans._double *= right->loadConstant()._int64;
			else
				ans._double *= right->loadConstant()._double;
			return ans;
		case DIV:
			if (left->getTypeConstant()->isInt())
				if (left->getTypeConstant()->isUnsigned)
					ans._double = left->loadConstant()._uint64;
				else
					ans._double = left->loadConstant()._int64;
			else
				ans._double = left->loadConstant()._double;
			if (right->getTypeConstant()->isFloat())
				if (right->getTypeConstant()->isUnsigned)
					ans._double /= right->loadConstant()._uint64;
				else
					ans._double /= right->loadConstant()._int64;
			else
				ans._double /= right->loadConstant()._double;
			return ans;
		case LSH:
		case RSH:
		case MOD:
			throw InvalidType(std::string("can't apply operator ") + OpNames[op] + " to " + left->getTypeConstant()->getName() + " and " + right->getTypeConstant()->getName());
		case LT:
			if (left->getTypeConstant()->isInt())
				if (left->getTypeConstant()->isUnsigned)
					ans._double = left->loadConstant()._uint64;
				else
					ans._double = left->loadConstant()._int64;
			else
				ans._double = left->loadConstant()._double;
			if (right->getTypeConstant()->isInt())
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._double < right->loadConstant()._uint64;
				else
					ans._bool = ans._double < right->loadConstant()._int64;
			else
				ans._bool = ans._double < right->loadConstant()._double;
			return ans;
		case LEQ:
			if (left->getTypeConstant()->isInt())
				if (left->getTypeConstant()->isUnsigned)
					ans._double = left->loadConstant()._uint64;
				else
					ans._double = left->loadConstant()._int64;
			else
				ans._double = left->loadConstant()._double;
			if (right->getTypeConstant()->isInt())
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._double <= right->loadConstant()._uint64;
				else
					ans._bool = ans._double <= right->loadConstant()._int64;
			else
				ans._bool = ans._double <= right->loadConstant()._double;
			return ans;
		case GT:
			if (left->getTypeConstant()->isInt())
				if (left->getTypeConstant()->isUnsigned)
					ans._double = left->loadConstant()._uint64;
				else
					ans._double = left->loadConstant()._int64;
			else
				ans._double = left->loadConstant()._double;
			if (right->getTypeConstant()->isInt())
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._double > right->loadConstant()._uint64;
				else
					ans._bool = ans._double > right->loadConstant()._int64;
			else
				ans._bool = ans._double > right->loadConstant()._double;
			return ans;
		case GEQ:
			if (left->getTypeConstant()->isInt())
				if (left->getTypeConstant()->isUnsigned)
					ans._double = left->loadConstant()._uint64;
				else
					ans._double = left->loadConstant()._int64;
			else
				ans._double = left->loadConstant()._double;
			if (right->getTypeConstant()->isInt())
				if (right->getTypeConstant()->isUnsigned)
					ans._bool = ans._double >= right->loadConstant()._uint64;
				else
					ans._bool = ans._double >= right->loadConstant()._int64;
			else
				ans._bool = ans._double >= right->loadConstant()._double;
			return ans;
		default:
			throw NotImplemented(std::string("operator ") + OpNames[op] + " not implemented");
		}
	else if (higherType->isString())
		throw NotImplemented("constant string calculate");
	throw NotImplemented(std::string("constant caculation ") + left->getTypeConstant()->getName() +
			OpNames[op] + right->getTypeConstant()->getName());
}
Example #11
0
void parser(action *lexems, int size)
{
	stack<StackType> stackMemory;
	StackType buf;
	buf.code = S;
	buf.name = "";
	stackMemory.push(buf);
	int i = 0;
	while(!stackMemory.empty())
	{
		bool flag = false, f = false;
		buf = stackMemory.top();
		if(i < size -1 ) print_el(array[i]), cout<<" ", print_el(array[i+1]);
		else print_el(array[i]);
		cout<<" ? ";
		print_stack(stackMemory);
		stackMemory.pop();
	//	cout<<"  "<<lexems[i].id_name<<""<<endl;
		if(lexems[i].code == buf.code)
		{
			if(lexems[i].code == id || lexems[i].code == lable) f = true, i++;
			else if(lexems[i].id_name == buf.name)  f = true, i++;
		}

		else
			switch(buf.code)
			{
				f = false;
				case S:
					if(lexems[i].code == keyword && lexems[i].id_name == "$") return;
					if(lexems[i].code == semicolon ) rules2(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "dim" ) rules1(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "set") rules2(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "do") rules2(stackMemory), f = true;	
					if(lexems[i].code == keyword && lexems[i].id_name == "for") rules2(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "if") rules2(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "cin") rules2(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "cout") rules2(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "goto") rules2(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "fail") rules2(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "select") rules2(stackMemory), f = true;
					if(lexems[i].code == lable) rules2(stackMemory), f = true;					
					if(!f) throw InvalidBegin();
					break;
				case X:
					if(lexems[i].code == keyword && lexems[i].id_name == "dim" ) rules3(stackMemory), f = true;
					if(!f) throw InvalidDeclaringVariables();
					break;
				case X1:  
					if(lexems[i].code == semicolon) 
					{
						if(lexems[i+1].code == keyword && lexems[i+1].id_name == "$" ) rules6(stackMemory), f = true;
						if(lexems[i+1].code == keyword && lexems[i+1].id_name == "dim" ) rules7(stackMemory), f = true;
						if(!f) rules8(stackMemory), f = true;
						//if(lexems[i+1].code == keyword && lexems[i+1].id_name == "set") rules8(stackMemory), f = true;
					//	if(lexems[i+1].code != keyword) rules8(stackMemory), f = true;

						//else   rules8(stackMemory), f = true; 
					}
					if(!f) throw InvalidType();
					break;
				case G:
					if(lexems[i].code == id)
					{
						f = true;
						if(lexems[i+1].code == coma) rules10(stackMemory);
						else rules9(stackMemory);
					}
					if(!f) throw InvalidDeclaring();
					break;

				case TYPE:
					if(lexems[i].code == keyword)
					{
						if(lexems[i].id_name == "BV")  rules5(stackMemory), f = true; 
						if(lexems[i].id_name == "INT")  rules4(stackMemory), f = true;
					}
					if(!f) throw InvalidType();
					break;
				
			case P:
				if(lexems[i].code == semicolon )
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "$" )  rules11(stackMemory), f = true;
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "case" )  rules11(stackMemory), f = true;
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "ni" )  rules11(stackMemory), f = true;
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "otherwise" )  rules11(stackMemory), f = true;
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "while" )  rules11(stackMemory), f = true;
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "od" )  rules11(stackMemory), f = true;
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "else" )  rules11(stackMemory), f = true;
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "fi" )  rules11(stackMemory), f = true;
					if(!f)  rules12(stackMemory), f = true;
				if(!f) throw InvalidEnd();
				break;
			case O:
				if(lexems[i].code == semicolon )rules13(stackMemory), f = true;
			//	if(lexems[i].code == keyword && lexems[i].id_name == "case") rules13(stackMemory), f = true;
			//	if(lexems[i].code == keyword && lexems[i].id_name == "otherwise") rules13(stackMemory), f = true;
			//	if(lexems[i].code == keyword && lexems[i].id_name == "ni") rules13(stackMemory), f = true;
				if(lexems[i].code == keyword && lexems[i].id_name == "set") rules14(stackMemory), f = true;
				if(lexems[i].code == keyword && lexems[i].id_name == "do") rules15(stackMemory), f = true;
				if(lexems[i].code == keyword && lexems[i].id_name == "for") rules27(stackMemory), f = true;
				if(lexems[i].code == keyword && lexems[i].id_name == "if") rules30(stackMemory), f = true;
				if(lexems[i].code == keyword && lexems[i].id_name == "cin") rules33(stackMemory), f = true;
				if(lexems[i].code == keyword && lexems[i].id_name == "cout") rules36(stackMemory), f = true;
				if(lexems[i].code == lable)  
					if(lexems[i+1].code == keyword && lexems[i+1].id_name == "$") rules39(stackMemory), f = true;
					else rules40(stackMemory), f = true;
				if(lexems[i].code == keyword && lexems[i].id_name == "goto") rules41(stackMemory), f = true;
				if(lexems[i].code == keyword && lexems[i].id_name == "fail")
					if(lexems[i+1].code == semicolon) rules42(stackMemory), f = true;
					else rules43(stackMemory), f = true;
			//	cout<<lexems[i].id_name<<endl;
				if(lexems[i].code == keyword && lexems[i].id_name == "select") rules44(stackMemory), f = true;
				if(!f) throw InvalidOperator();
				break;
			case W:
				if(lexems[i].code == semicolon) rules16(stackMemory), f = true;
				if(lexems[i].code == lable) rules16(stackMemory), f = true;
				if(lexems[i].code == keyword)
				{
					if(lexems[i].id_name == "set" || lexems[i].id_name == "do" || lexems[i].id_name == "for" ) rules16(stackMemory), f = true;
					if(lexems[i].id_name == "cin" || lexems[i].id_name == "cout" ) rules16(stackMemory), f = true;
					if(lexems[i].id_name == "while") rules17(stackMemory), f = true;
					if(lexems[i].code == lable)rules16(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "goto") rules16(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "fail") rules16(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "select") rules16(stackMemory), f = true;
					if(lexems[i].code == keyword && lexems[i].id_name == "if") rules16(stackMemory), f = true;
				}
				if(!f) throw InvalidOperatorWhile(); 
				break;
			case W1:
				if(lexems[i].code == semicolon) rules18(stackMemory), f = true;
				if(lexems[i].code == lable) rules18(stackMemory), f = true;
				if(lexems[i].code == keyword)
				{
					if(lexems[i].id_name == "set" || lexems[i].id_name == "do" 
						||  lexems[i].id_name == "for" || lexems[i].id_name == "cout"
						|| lexems[i].id_name == "cin" ) rules18(stackMemory), f = true;
					if(lexems[i].id_name == "goto") rules18(stackMemory), f = true;
					if(lexems[i].id_name == "if") rules18(stackMemory), f = true;
					if(lexems[i].id_name == "fail") rules18(stackMemory), f = true;
					if(lexems[i].id_name == "select") rules18(stackMemory), f = true;
					if(lexems[i].id_name == "od") rules19(stackMemory), f = true;
				}
				if(!f) throw InvalidOperatorWhile(); 
				break;		
			case T:
				if(lexems[i].code == id || lexems[i].code == CONST 
					|| lexems[i].code == lbr || lexems[i].code == otr 
					|| lexems[i].code == lfs || lexems[i].code == rs  
					|| lexems[i].code == ls) rules20(stackMemory), f = true;
				if(!f) throw InvalidTest();
				break;
			case T1: 
				if(lexems[i].code == Equal) rules21(stackMemory), f = true;
				if(lexems[i].code == not_equal) rules22(stackMemory), f = true;
				if(lexems[i].code == more) rules23(stackMemory), f = true;
				if(lexems[i].code == Less) rules24(stackMemory), f = true;
				if(lexems[i].code == more_or_equal) rules25(stackMemory), f = true;
				if(lexems[i].code == less_or_equal) rules26(stackMemory), f = true;
				if(!f) throw InvalidRatio();
				break;		
			case F:
				if(lexems[i].code == keyword &&  lexems[i].id_name == "by") rules28(stackMemory), f = true;
				if(lexems[i].code == keyword &&  lexems[i].id_name == "do") rules29(stackMemory), f = true;
				if(!f) throw InvalidOperatorFor();
				break;
			case N:
				if(lexems[i].code == keyword &&  lexems[i].id_name == "else") rules31(stackMemory), f = true;
				if(lexems[i].code == keyword &&  lexems[i].id_name == "fi") rules32(stackMemory), f = true;
				if(!f) throw InvalidOperatorIf();
				break;
			case I:
				if(lexems[i].code == semicolon ) rules34(stackMemory), f = true;
				if(lexems[i].code == in ) rules35(stackMemory), f = true;  
				if(!f) throw InvalidOperatorCin();
				break;
			case U:
				if(lexems[i].code == semicolon ) rules37(stackMemory), f = true;
				if(lexems[i].code == out ) rules38(stackMemory), f = true;  
				if(!f) throw InvalidOperatorCout();
				break;
			case K:
				if(lexems[i].code == keyword &&  lexems[i].id_name == "case") rules45(stackMemory), f = true;
				if(lexems[i].code == keyword &&  lexems[i].id_name == "otherwise") rules46(stackMemory), f = true;
				if(lexems[i].code == keyword &&  lexems[i].id_name == "ni") rules47(stackMemory), f = true;
				if(!f) throw InvalidOperatorSelect();
				break;
			case E:
				if(lexems[i].code == id || lexems[i].code == CONST 
					|| lexems[i].code == lbr || lexems[i].code == otr 
					|| lexems[i].code == lfs || lexems[i].code == rs  
					|| lexems[i].code == ls) rules48(stackMemory), f = true;
				if(!f) throw InvalidExpression();
				break;
			case A:
				if(lexems[i].code == id || lexems[i].code == CONST 
					|| lexems[i].code == lbr || lexems[i].code == otr 
					|| lexems[i].code == lfs || lexems[i].code == rs  
					|| lexems[i].code == ls) rules49(stackMemory), f = true; 
				if(!f) throw InvalidExpression();
				break;
			case B:
				if(lexems[i].code == id || lexems[i].code == CONST 
					|| lexems[i].code == lbr || lexems[i].code == otr 
					|| lexems[i].code == lfs || lexems[i].code == rs  
					|| lexems[i].code == ls) rules50(stackMemory), f = true; 
				if(!f) throw InvalidExpression();
				break;
			case D:
				if(lexems[i].code == id || lexems[i].code == CONST 
					|| lexems[i].code == lbr || lexems[i].code == otr 
					|| lexems[i].code == lfs || lexems[i].code == rs  
					|| lexems[i].code == ls) rules51(stackMemory), f = true; 
				if(!f) throw InvalidExpression();
				break;
			case H:
				if(lexems[i].code == id || lexems[i].code == CONST 
					|| lexems[i].code == lbr || lexems[i].code == otr 
					|| lexems[i].code == lfs || lexems[i].code == rs  
					|| lexems[i].code == ls) rules52(stackMemory), f = true; 
				if(!f) throw InvalidExpression();
				break;
			case J:
				if(lexems[i].code == id || lexems[i].code == CONST 
					|| lexems[i].code == lbr || lexems[i].code == otr 
					|| lexems[i].code == lfs ) rules55(stackMemory), f = true; 
				if(lexems[i].code == rs) rules53(stackMemory), f = true;
				if(lexems[i].code == ls) rules54(stackMemory), f = true;
				if(!f) throw InvalidExpression();
				break;
			case L:
				if(lexems[i].code == id || lexems[i].code == CONST 
					|| lexems[i].code == lbr || lexems[i].code == otr) rules57(stackMemory), f = true;
				if(lexems[i].code == lfs) rules56(stackMemory), f = true;
				if(!f) throw InvalidExpression();
				break;
			case Z:
				if(lexems[i].code == id)  rules59(stackMemory), f = true;
				if(lexems[i].code == CONST) rules60(stackMemory), f = true;
				if(lexems[i].code == lbr) rules61(stackMemory), f = true;
				if(lexems[i].code == otr) rules58(stackMemory), f = true;
				if(!f) throw InvalidExpression();
				break;
			case ID:
				if(lexems[i].code == id)
				{
					if(lexems[i+1].code == AND) rules77(stackMemory), f = true;
					if(lexems[i+1].code == OR) rules78(stackMemory), f = true;
					if(lexems[i+1].code == Xor) rules79(stackMemory), f = true;
					if(lexems[i+1].code == ssh) rules80(stackMemory), f = true;
					if(lexems[i+1].code == sl) rules81(stackMemory), f = true;
					if(lexems[i+1].code == conc) rules82(stackMemory), f = true;
					if(lexems[i+1].code == scolar) rules83(stackMemory), f = true;
					if(lexems[i+1].code == sp) rules84(stackMemory), f = true;
					if(lexems[i+1].code == multy) rules85(stackMemory), f = true;
					if(lexems[i+1].code == DEV) rules86(stackMemory), f = true;
					if(lexems[i+1].code == MOD) rules87(stackMemory), f = true;
					if(lexems[i+1].code == add) rules88(stackMemory), f = true;
					if(lexems[i+1].code == sub) rules89(stackMemory), f = true;
					if(!f)  rules90(stackMemory), f = true;
				}
				if(!f) throw InvalidExpression();
				break;
			case C:
				if(lexems[i].code == CONST)
				{
					if(lexems[i+1].code == AND) rules92(stackMemory), f = true;
					if(lexems[i+1].code == OR) rules93(stackMemory), f = true;
					if(lexems[i+1].code == Xor) rules94(stackMemory), f = true;
					if(lexems[i+1].code == ssh) rules95(stackMemory), f = true;
					if(lexems[i+1].code == sl) rules96(stackMemory), f = true;
					if(lexems[i+1].code == conc) rules97(stackMemory), f = true;
					if(lexems[i+1].code == scolar) rules98(stackMemory), f = true;
					if(lexems[i+1].code == sp) rules99(stackMemory), f = true;
					if(lexems[i+1].code == multy) rules100(stackMemory), f = true;
					if(lexems[i+1].code == DEV) rules101(stackMemory), f = true;
					if(lexems[i+1].code == MOD) rules102(stackMemory), f = true;
					if(lexems[i+1].code == add) rules103(stackMemory), f = true;
					if(lexems[i+1].code == sub) rules104(stackMemory), f = true;
					if(!f)  rules105(stackMemory), f = true;
				}
				if(!f) throw InvalidExpression();
				break;
			case SH:
				if(lexems[i].code == rbr)
				{
					if(lexems[i+1].code == AND) rules62(stackMemory), f = true;
					if(lexems[i+1].code == OR) rules63(stackMemory), f = true;
					if(lexems[i+1].code == Xor) rules64(stackMemory), f = true;
					if(lexems[i+1].code == ssh) rules65(stackMemory), f = true;
					if(lexems[i+1].code == sl) rules66(stackMemory), f = true;
					if(lexems[i+1].code == conc) rules67(stackMemory), f = true;
					if(lexems[i+1].code == scolar) rules68(stackMemory), f = true;
					if(lexems[i+1].code == sp) rules69(stackMemory), f = true;
					if(lexems[i+1].code == multy) rules70(stackMemory), f = true;
					if(lexems[i+1].code == DEV) rules71(stackMemory), f = true;
					if(lexems[i+1].code == MOD) rules72(stackMemory), f = true;
					if(lexems[i+1].code == add) rules73(stackMemory), f = true;
					if(lexems[i+1].code == sub) rules74(stackMemory), f = true;
					if(!f)  rules75(stackMemory), f = true;
				}
				if(!f) throw InvalidExpression();
				break;
			case G1:
					if(lexems[i].code == id)
					{
						f = true;
						if(lexems[i+1].code == coma) rules107(stackMemory);
						else rules106(stackMemory);
					}
					if(!f) throw InvalidDeclaring();
					break;

			default: cout<<"ERRRRORRRRR"<<endl; return;
			}

	}

	cout<<lexems[i].id_name<<""<<endl;
	if(lexems[i].id_name == "$" && stackMemory.empty()) cout<<"acc"<<endl;
	else cout<<"fail"<<endl;
}