This commit is contained in:
Daniel Kirchner 2023-06-25 04:22:13 +02:00
parent 947deaec96
commit 6f352cbcbe
9 changed files with 73 additions and 6 deletions

View File

@ -349,7 +349,7 @@ namespace TokenTraits
{ {
return tok == Token::Assembly || tok == Token::Contract || tok == Token::External || tok == Token::Fallback || return tok == Token::Assembly || tok == Token::Contract || tok == Token::External || tok == Token::Fallback ||
tok == Token::Pragma || tok == Token::Import || tok == Token::As || tok == Token::Function || tok == Token::Let || tok == Token::Pragma || tok == Token::Import || tok == Token::As || tok == Token::Function || tok == Token::Let ||
tok == Token::Return || tok == Token::Type || (tok > Token::NonExperimentalEnd && tok < Token::ExperimentalEnd); tok == Token::Return || tok == Token::Type || tok == Token::Bool || (tok > Token::NonExperimentalEnd && tok < Token::ExperimentalEnd);
} }
constexpr bool isExperimentalSolidityOnlyKeyword(Token tok) constexpr bool isExperimentalSolidityOnlyKeyword(Token tok)
{ {

View File

@ -48,6 +48,7 @@ m_typeSystem(_analysis.typeSystem())
m_wordType = m_typeSystem.type(BuiltinType::Word, {}); m_wordType = m_typeSystem.type(BuiltinType::Word, {});
m_integerType = m_typeSystem.type(BuiltinType::Integer, {}); m_integerType = m_typeSystem.type(BuiltinType::Integer, {});
m_unitType = m_typeSystem.type(BuiltinType::Unit, {}); m_unitType = m_typeSystem.type(BuiltinType::Unit, {});
m_boolType = m_typeSystem.type(BuiltinType::Bool, {});
m_env = &m_typeSystem.env(); m_env = &m_typeSystem.env();
} }
@ -272,6 +273,9 @@ bool TypeInference::visit(ElementaryTypeNameExpression const& _expression)
case Token::Unit: case Token::Unit:
expressionAnnotation.type = helper.kindType(m_unitType); expressionAnnotation.type = helper.kindType(m_unitType);
break; break;
case Token::Bool:
expressionAnnotation.type = helper.kindType(m_boolType);
break;
case Token::Pair: case Token::Pair:
{ {
auto leftType = m_typeSystem.freshTypeVariable(false, {}); auto leftType = m_typeSystem.freshTypeVariable(false, {});
@ -1055,7 +1059,6 @@ optional<rational> rationalValue(Literal const& _literal)
bool TypeInference::visit(Literal const& _literal) bool TypeInference::visit(Literal const& _literal)
{ {
auto& literalAnnotation = annotation(_literal); auto& literalAnnotation = annotation(_literal);
literalAnnotation.type = m_typeSystem.freshTypeVariable(false, {});
if (_literal.token() != Token::Number) if (_literal.token() != Token::Number)
{ {
m_errorReporter.typeError(0000_error, _literal.location(), "Only number literals are supported."); m_errorReporter.typeError(0000_error, _literal.location(), "Only number literals are supported.");
@ -1072,5 +1075,6 @@ bool TypeInference::visit(Literal const& _literal)
m_errorReporter.typeError(0000_error, _literal.location(), "Only integers are supported."); m_errorReporter.typeError(0000_error, _literal.location(), "Only integers are supported.");
return false; return false;
} }
literalAnnotation.type = m_typeSystem.freshTypeVariable(false, Sort{{TypeClass{BuiltinClass::Integer}}});
return false; return false;
} }

View File

@ -94,6 +94,7 @@ private:
Type m_wordType; Type m_wordType;
Type m_integerType; Type m_integerType;
Type m_unitType; Type m_unitType;
Type m_boolType;
std::optional<Type> m_currentFunctionType; std::optional<Type> m_currentFunctionType;
Annotation& annotation(ASTNode const& _node); Annotation& annotation(ASTNode const& _node);

View File

@ -41,7 +41,8 @@ m_typeSystem(_analysis.typeSystem())
{BuiltinType::Unit, "unit", 0}, {BuiltinType::Unit, "unit", 0},
{BuiltinType::Pair, "pair", 2}, {BuiltinType::Pair, "pair", 2},
{BuiltinType::Word, "word", 0}, {BuiltinType::Word, "word", 0},
{BuiltinType::Integer, "integer", 0} {BuiltinType::Integer, "integer", 0},
{BuiltinType::Bool, "bool", 0}
}) })
m_typeSystem.declareTypeConstructor(type, name, arity); m_typeSystem.declareTypeConstructor(type, name, arity);
@ -80,6 +81,23 @@ m_typeSystem(_analysis.typeSystem())
defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul"); defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul");
defineBinaryMonoidalOperator(BuiltinClass::Add, Token::Add, "add"); defineBinaryMonoidalOperator(BuiltinClass::Add, Token::Add, "add");
auto defineBinaryCompareOperator = [&](BuiltinClass _class, Token _token, std::string _name) {
declareBuiltinClass(_class, [&](Type _typeVar) -> MemberList {
return {
{
_name,
helper.functionType(helper.tupleType({_typeVar, _typeVar}), TypeConstant{BuiltinType::Bool, {}})
}
};
});
annotation().operators[_token] = std::make_tuple(TypeClass{_class}, _name);
};
defineBinaryCompareOperator(BuiltinClass::Equal, Token::Equal, "eq");
defineBinaryCompareOperator(BuiltinClass::Less, Token::LessThan, "lt");
defineBinaryCompareOperator(BuiltinClass::LessOrEqual, Token::LessThanOrEqual, "leq");
defineBinaryCompareOperator(BuiltinClass::Greater, Token::GreaterThan, "gt");
defineBinaryCompareOperator(BuiltinClass::GreaterOrEqual, Token::GreaterThanOrEqual, "geq");
} }
bool TypeRegistration::analyze(SourceUnit const& _sourceUnit) bool TypeRegistration::analyze(SourceUnit const& _sourceUnit)

View File

@ -77,6 +77,16 @@ string TypeClass::toString() const
return "*"; return "*";
case BuiltinClass::Add: case BuiltinClass::Add:
return "+"; return "+";
case BuiltinClass::Equal:
return "==";
case BuiltinClass::Less:
return "<";
case BuiltinClass::LessOrEqual:
return "<=";
case BuiltinClass::Greater:
return ">";
case BuiltinClass::GreaterOrEqual:
return ">=";
} }
solAssert(false); solAssert(false);
}, },

View File

@ -47,6 +47,7 @@ enum class BuiltinType
Unit, Unit,
Pair, Pair,
Word, Word,
Bool,
Integer Integer
}; };
@ -75,7 +76,12 @@ enum class BuiltinClass
Constraint, Constraint,
Integer, Integer,
Mul, Mul,
Add Add,
Equal,
Less,
LessOrEqual,
Greater,
GreaterOrEqual
}; };
struct TypeClass struct TypeClass

View File

@ -85,6 +85,9 @@ std::string TypeEnvironment::canonicalTypeName(Type _type) const
case BuiltinType::Word: case BuiltinType::Word:
stream << "word"; stream << "word";
break; break;
case BuiltinType::Bool:
stream << "bool";
break;
case BuiltinType::Integer: case BuiltinType::Integer:
stream << "integer"; stream << "integer";
break; break;

View File

@ -62,6 +62,8 @@ std::optional<TypeConstructor> experimental::typeConstructorFromToken(langutil::
return BuiltinType::Word; return BuiltinType::Word;
case Token::Integer: case Token::Integer:
return BuiltinType::Integer; return BuiltinType::Integer;
case Token::Bool:
return BuiltinType::Bool;
default: default:
return nullopt; return nullopt;
} }
@ -77,6 +79,16 @@ std::optional<TypeClass> experimental::typeClassFromToken(langutil::Token _token
return TypeClass{BuiltinClass::Mul}; return TypeClass{BuiltinClass::Mul};
case Token::Add: case Token::Add:
return TypeClass{BuiltinClass::Add}; return TypeClass{BuiltinClass::Add};
case Token::Equal:
return TypeClass{BuiltinClass::Equal};
case Token::LessThan:
return TypeClass{BuiltinClass::Less};
case Token::LessThanOrEqual:
return TypeClass{BuiltinClass::LessOrEqual};
case Token::GreaterThan:
return TypeClass{BuiltinClass::Greater};
case Token::GreaterThanOrEqual:
return TypeClass{BuiltinClass::GreaterOrEqual};
default: default:
return nullopt; return nullopt;
} }

View File

@ -32,15 +32,28 @@ instantiation word: * {
} }
} }
instantiation word: integer {
function fromInteger(x:integer) -> y:word {
}
}
instantiation word: == {
function eq(x, y) -> z:bool {
assembly {
x := eq(x, y)
}
}
}
contract C { contract C {
fallback() external { fallback() external {
let x : word; let x : word;
assembly { assembly {
x := 0x10 x := 0x10
} }
let w: uint256 = uint256.abs(x); let w = uint256.abs(x);
w = w * w + w; w = w * w + w;
let y : word = 2; let y : word;
assembly { y := 2 } assembly { y := 2 }
y = uint256.rep(w) * y; y = uint256.rep(w) * y;
assembly { assembly {