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 ||
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)
{

View File

@ -48,6 +48,7 @@ m_typeSystem(_analysis.typeSystem())
m_wordType = m_typeSystem.type(BuiltinType::Word, {});
m_integerType = m_typeSystem.type(BuiltinType::Integer, {});
m_unitType = m_typeSystem.type(BuiltinType::Unit, {});
m_boolType = m_typeSystem.type(BuiltinType::Bool, {});
m_env = &m_typeSystem.env();
}
@ -272,6 +273,9 @@ bool TypeInference::visit(ElementaryTypeNameExpression const& _expression)
case Token::Unit:
expressionAnnotation.type = helper.kindType(m_unitType);
break;
case Token::Bool:
expressionAnnotation.type = helper.kindType(m_boolType);
break;
case Token::Pair:
{
auto leftType = m_typeSystem.freshTypeVariable(false, {});
@ -1055,7 +1059,6 @@ optional<rational> rationalValue(Literal const& _literal)
bool TypeInference::visit(Literal const& _literal)
{
auto& literalAnnotation = annotation(_literal);
literalAnnotation.type = m_typeSystem.freshTypeVariable(false, {});
if (_literal.token() != Token::Number)
{
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.");
return false;
}
literalAnnotation.type = m_typeSystem.freshTypeVariable(false, Sort{{TypeClass{BuiltinClass::Integer}}});
return false;
}

View File

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

View File

@ -41,7 +41,8 @@ m_typeSystem(_analysis.typeSystem())
{BuiltinType::Unit, "unit", 0},
{BuiltinType::Pair, "pair", 2},
{BuiltinType::Word, "word", 0},
{BuiltinType::Integer, "integer", 0}
{BuiltinType::Integer, "integer", 0},
{BuiltinType::Bool, "bool", 0}
})
m_typeSystem.declareTypeConstructor(type, name, arity);
@ -80,6 +81,23 @@ m_typeSystem(_analysis.typeSystem())
defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul");
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)

View File

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

View File

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

View File

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

View File

@ -62,6 +62,8 @@ std::optional<TypeConstructor> experimental::typeConstructorFromToken(langutil::
return BuiltinType::Word;
case Token::Integer:
return BuiltinType::Integer;
case Token::Bool:
return BuiltinType::Bool;
default:
return nullopt;
}
@ -77,6 +79,16 @@ std::optional<TypeClass> experimental::typeClassFromToken(langutil::Token _token
return TypeClass{BuiltinClass::Mul};
case Token::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:
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 {
fallback() external {
let x : word;
assembly {
x := 0x10
}
let w: uint256 = uint256.abs(x);
let w = uint256.abs(x);
w = w * w + w;
let y : word = 2;
let y : word;
assembly { y := 2 }
y = uint256.rep(w) * y;
assembly {