mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
tmp
This commit is contained in:
parent
d882a08582
commit
947deaec96
@ -184,55 +184,6 @@ bool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
optional<TypeConstructor> TypeInference::fromTypeName(TypeName const& _typeName)
|
|
||||||
{
|
|
||||||
if (auto const* elementaryTypeName = dynamic_cast<ElementaryTypeName const*>(&_typeName))
|
|
||||||
{
|
|
||||||
switch(elementaryTypeName->typeName().token())
|
|
||||||
{
|
|
||||||
case Token::Void:
|
|
||||||
return BuiltinType::Void;
|
|
||||||
case Token::Fun:
|
|
||||||
return BuiltinType::Function;
|
|
||||||
case Token::Unit:
|
|
||||||
return BuiltinType::Unit;
|
|
||||||
case Token::Pair:
|
|
||||||
return BuiltinType::Pair;
|
|
||||||
case Token::Word:
|
|
||||||
return BuiltinType::Word;
|
|
||||||
case Token::Integer:
|
|
||||||
return BuiltinType::Integer;
|
|
||||||
default:
|
|
||||||
m_errorReporter.typeError(0000_error, _typeName.location(), "Only elementary types are supported.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (auto const* userDefinedTypeName = dynamic_cast<UserDefinedTypeName const*>(&_typeName))
|
|
||||||
{
|
|
||||||
auto const* declaration = userDefinedTypeName->pathNode().annotation().referencedDeclaration;
|
|
||||||
solAssert(declaration);
|
|
||||||
if (auto const* variableDeclaration = dynamic_cast<VariableDeclaration const*>(declaration))
|
|
||||||
{
|
|
||||||
if (auto const* typeClass = dynamic_cast<TypeClassDefinition const*>(variableDeclaration->scope()))
|
|
||||||
{
|
|
||||||
typeClass->accept(*this);
|
|
||||||
auto varType = annotation(typeClass->typeVariable()).type;
|
|
||||||
solAssert(varType);
|
|
||||||
return *varType;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_errorReporter.typeError(0000_error, _typeName.location(), "Type name referencing a variable declaration.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_errorReporter.typeError(0000_error, _typeName.location(), "Unsupported user defined type name.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_errorReporter.typeError(0000_error, _typeName.location(), "Unsupported type name.");
|
|
||||||
return m_typeSystem.freshTypeVariable(false, {});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void TypeInference::unify(Type _a, Type _b, langutil::SourceLocation _location, TypeEnvironment* _env)
|
void TypeInference::unify(Type _a, Type _b, langutil::SourceLocation _location, TypeEnvironment* _env)
|
||||||
{
|
{
|
||||||
if (!_env)
|
if (!_env)
|
||||||
@ -791,28 +742,9 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation)
|
|||||||
functionTypes[functionDefinition->name()] = *annotation(*functionDefinition).type;
|
functionTypes[functionDefinition->name()] = *annotation(*functionDefinition).type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (auto error = m_typeSystem.instantiateClass(type, arity, std::move(functionTypes)))
|
if (auto error = m_typeSystem.instantiateClass(type, arity, std::move(functionTypes)))
|
||||||
m_errorReporter.typeError(0000_error, _typeClassInstantiation.location(), *error);
|
m_errorReporter.typeError(0000_error, _typeClassInstantiation.location(), *error);
|
||||||
/*
|
|
||||||
TypeEnvironment newEnv = m_env->clone();
|
|
||||||
|
|
||||||
|
|
||||||
for (auto subNode: _typeClassInstantiation.subNodes())
|
|
||||||
{
|
|
||||||
auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(subNode.get());
|
|
||||||
if (Type* expectedFunctionType = util::valueOrNullptr(functionTypes, functionDefinition->name()))
|
|
||||||
{
|
|
||||||
auto functionType = annotation(*functionDefinition).type;
|
|
||||||
solAssert(functionType);
|
|
||||||
// TODO: require exact match?
|
|
||||||
unify(*functionType, *expectedFunctionType, functionDefinition->location());
|
|
||||||
functionTypes.erase(functionDefinition->name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!functionTypes.empty())
|
|
||||||
m_errorReporter.typeError(0000_error, _typeClassInstantiation.location(), "Type class instantiation does not implement all required functions.");
|
|
||||||
*/
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,43 +788,6 @@ bool TypeInference::visit(MemberAccess const& _memberAccess)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
/*
|
|
||||||
_memberAccess.expression().accept(*this);
|
|
||||||
if (auto const* identifier = dynamic_cast<Identifier const*>(&_memberAccess.expression()))
|
|
||||||
{
|
|
||||||
auto const* declaration = identifier->annotation().referencedDeclaration;
|
|
||||||
if (auto const* typeClass = dynamic_cast<TypeClassDefinition const*>(declaration))
|
|
||||||
{
|
|
||||||
for (auto subNode: typeClass->subNodes())
|
|
||||||
{
|
|
||||||
if (auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(subNode.get()))
|
|
||||||
{
|
|
||||||
if (functionDefinition->name() == _memberAccess.memberName())
|
|
||||||
{
|
|
||||||
auto& declarationAnnotation = annotation(*functionDefinition);
|
|
||||||
if (!declarationAnnotation.type)
|
|
||||||
functionDefinition->accept(*this);
|
|
||||||
solAssert(declarationAnnotation.type);
|
|
||||||
Type type = m_env->fresh(*declarationAnnotation.type, true);
|
|
||||||
annotation(_memberAccess).type = type;
|
|
||||||
auto typeVars = TypeSystemHelpers{m_typeSystem}.typeVars(type);
|
|
||||||
if (typeVars.size() != 1)
|
|
||||||
m_errorReporter.typeError(0000_error, _memberAccess.location(), "Type class reference does not uniquely depend on class type.");
|
|
||||||
annotation(_memberAccess.expression()).type = typeVars.front();
|
|
||||||
m_errorReporter.info(0000_error, _memberAccess.location(), m_env->typeToString(*declarationAnnotation.type));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_errorReporter.fatalTypeError(0000_error, _memberAccess.location(), "Unknown member of type-class.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_errorReporter.fatalTypeError(0000_error, _memberAccess.location(), "Member access to non-type-class.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_errorReporter.fatalTypeError(0000_error, _memberAccess.location(), "Member access to non-identifier.");
|
|
||||||
|
|
||||||
return false;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeInference::visit(TypeDefinition const& _typeDefinition)
|
bool TypeInference::visit(TypeDefinition const& _typeDefinition)
|
||||||
|
@ -65,15 +65,21 @@ m_typeSystem(_analysis.typeSystem())
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
declareBuiltinClass(BuiltinClass::Mul, [&](Type _typeVar) -> MemberList {
|
|
||||||
return {
|
auto defineBinaryMonoidalOperator = [&](BuiltinClass _class, Token _token, std::string _name) {
|
||||||
{
|
declareBuiltinClass(_class, [&](Type _typeVar) -> MemberList {
|
||||||
"mul",
|
return {
|
||||||
helper.functionType(helper.tupleType({_typeVar, _typeVar}), _typeVar)
|
{
|
||||||
}
|
_name,
|
||||||
};
|
helper.functionType(helper.tupleType({_typeVar, _typeVar}), _typeVar)
|
||||||
});
|
}
|
||||||
annotation().operators[Token::Mul] = std::make_tuple(TypeClass{BuiltinClass::Mul}, "mul");
|
};
|
||||||
|
});
|
||||||
|
annotation().operators[_token] = std::make_tuple(TypeClass{_class}, _name);
|
||||||
|
};
|
||||||
|
|
||||||
|
defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul");
|
||||||
|
defineBinaryMonoidalOperator(BuiltinClass::Add, Token::Add, "add");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeRegistration::analyze(SourceUnit const& _sourceUnit)
|
bool TypeRegistration::analyze(SourceUnit const& _sourceUnit)
|
||||||
|
@ -75,6 +75,8 @@ string TypeClass::toString() const
|
|||||||
return "integer";
|
return "integer";
|
||||||
case BuiltinClass::Mul:
|
case BuiltinClass::Mul:
|
||||||
return "*";
|
return "*";
|
||||||
|
case BuiltinClass::Add:
|
||||||
|
return "+";
|
||||||
}
|
}
|
||||||
solAssert(false);
|
solAssert(false);
|
||||||
},
|
},
|
||||||
|
@ -74,7 +74,8 @@ enum class BuiltinClass
|
|||||||
Kind,
|
Kind,
|
||||||
Constraint,
|
Constraint,
|
||||||
Integer,
|
Integer,
|
||||||
Mul
|
Mul,
|
||||||
|
Add
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeClass
|
struct TypeClass
|
||||||
|
@ -75,6 +75,8 @@ std::optional<TypeClass> experimental::typeClassFromToken(langutil::Token _token
|
|||||||
return TypeClass{BuiltinClass::Integer};
|
return TypeClass{BuiltinClass::Integer};
|
||||||
case Token::Mul:
|
case Token::Mul:
|
||||||
return TypeClass{BuiltinClass::Mul};
|
return TypeClass{BuiltinClass::Mul};
|
||||||
|
case Token::Add:
|
||||||
|
return TypeClass{BuiltinClass::Add};
|
||||||
default:
|
default:
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,18 @@ instantiation uint256: * {
|
|||||||
assembly {
|
assembly {
|
||||||
a := mul(a,b)
|
a := mul(a,b)
|
||||||
}
|
}
|
||||||
z = uint256.abs(a);
|
return uint256.abs(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instantiation uint256: + {
|
||||||
|
function add(x, y) -> z {
|
||||||
|
let a = uint256.rep(x);
|
||||||
|
let b = uint256.rep(y);
|
||||||
|
assembly {
|
||||||
|
a := add(a,b)
|
||||||
|
}
|
||||||
|
return uint256.abs(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,8 +39,8 @@ contract C {
|
|||||||
x := 0x10
|
x := 0x10
|
||||||
}
|
}
|
||||||
let w: uint256 = uint256.abs(x);
|
let w: uint256 = uint256.abs(x);
|
||||||
w = w * w;
|
w = w * w + w;
|
||||||
let y : word;
|
let y : word = 2;
|
||||||
assembly { y := 2 }
|
assembly { y := 2 }
|
||||||
y = uint256.rep(w) * y;
|
y = uint256.rep(w) * y;
|
||||||
assembly {
|
assembly {
|
||||||
|
Loading…
Reference in New Issue
Block a user