mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 15:08:45 +00:00
type_check_visitor value types maybe fixed
This commit is contained in:
parent
6bf64acc4d
commit
43b2993e2a
5 changed files with 76 additions and 65 deletions
|
|
@ -50,7 +50,7 @@ public:
|
|||
}
|
||||
|
||||
void ModifiyValue(utils::IdType value_id, utils::ValueType new_value_type) {
|
||||
GetValueType(value_id) = new_value_type;
|
||||
value_manager_.SetValueType(value_id, new_value_type);
|
||||
}
|
||||
|
||||
utils::IdType ToModifiedValue(utils::IdType value_id, utils::ValueType new_value_type) {
|
||||
|
|
@ -61,7 +61,7 @@ public:
|
|||
utils::IdType ToModifiedValueCopy(utils::IdType value_id,
|
||||
utils::ValueType new_value_type) {
|
||||
Value* value = GetAnyValue(value_id);
|
||||
return value->DeepCopy(value_manager_, new_value_type);
|
||||
return value->DeepCopy(&value_manager_, new_value_type);
|
||||
}
|
||||
|
||||
// make deep copy if not temporary
|
||||
|
|
|
|||
|
|
@ -377,10 +377,14 @@ public:
|
|||
return &types_.at(type_id).first;
|
||||
}
|
||||
|
||||
utils::ValueType& GetValueType(utils::IdType type_id) {
|
||||
utils::ValueType GetValueType(utils::IdType type_id) {
|
||||
return types_.at(type_id).second;
|
||||
}
|
||||
|
||||
void SetValueType(utils::IdType type_id, utils::ValueType value_type) {
|
||||
types_.at(type_id).second = value_type;
|
||||
}
|
||||
|
||||
bool EqualValues(utils::IdType first_type, utils::IdType second_type) {
|
||||
return GetAnyValue(first_type)->Same(*GetAnyValue(second_type));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,10 +223,14 @@ public:
|
|||
return &values_.at(value_id).first;
|
||||
}
|
||||
|
||||
utils::ValueType& GetValueType(utils::IdType value_id) {
|
||||
utils::ValueType GetValueType(utils::IdType value_id) {
|
||||
return values_.at(value_id).second;
|
||||
}
|
||||
|
||||
void SetValueType(utils::IdType value_id, utils::ValueType value_type) {
|
||||
values_.at(value_id).second = value_type;
|
||||
}
|
||||
|
||||
bool EqualValues(utils::IdType first_value, utils::IdType second_value) {
|
||||
return GetAnyValue(first_value)->Same(*GetAnyValue(second_value));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
|
|||
if (maybe_internal_type.has_value()) {
|
||||
if (HandleBuiltinTypeFunctionCall(node, maybe_internal_type.value())) {
|
||||
context_manager_.ExitContext();
|
||||
return; // TODO: always return from end of function
|
||||
return; // TODO: return from end of function
|
||||
}
|
||||
error_handling::HandleRuntimeError("Type function definition not found (builtin type)", node->base);
|
||||
}
|
||||
|
|
@ -995,6 +995,8 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
|
|||
info::type::InternalType type) {
|
||||
const std::string& name = node->name;
|
||||
|
||||
error_handling::DebugPrint(name);
|
||||
|
||||
if (utils::IsBuiltinFunction(name)) {
|
||||
std::vector<info::value::InternalValue*> arguments;
|
||||
arguments.reserve(node->arguments.size());
|
||||
|
|
@ -1009,8 +1011,8 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
|
|||
arguments.push_back(ExtractValue<info::value::InternalValue>(current_value_, node->base));
|
||||
}
|
||||
|
||||
// error_handling::DebugPrint(info::type::ToString(type));
|
||||
// std::cout << std::endl;
|
||||
error_handling::DebugPrint(info::type::ToString(type));
|
||||
std::cout << std::endl;
|
||||
|
||||
switch (type) {
|
||||
case info::type::InternalType::Float:
|
||||
|
|
@ -1035,10 +1037,22 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
|
|||
info::value::InternalValue(1.0),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "+=") {
|
||||
// TODO
|
||||
error_handling::HandleInternalError("+= not implemented yet (float)",
|
||||
"ExecuteVisitor.HandleBuiltinTypeFunctionCall",
|
||||
&node->base);
|
||||
*arguments[0]->GetValue<double>().value() += *arguments[1]->GetValue<double>().value();
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "-=") {
|
||||
*arguments[0]->GetValue<double>().value() -= *arguments[1]->GetValue<double>().value();
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "*=") {
|
||||
*arguments[0]->GetValue<double>().value() *= *arguments[1]->GetValue<double>().value();
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "/=") {
|
||||
*arguments[0]->GetValue<double>().value() /= *arguments[1]->GetValue<double>().value();
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
|
|
@ -1063,7 +1077,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
|
|||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() / *arguments[1]->GetValue<int64_t>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "mod") { // TODO: best implementation of mod (read % specification)
|
||||
} else if (name == "mod") { // TODO: better implementation of mod (read % specification)
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() % *arguments[1]->GetValue<int64_t>().value()),
|
||||
utils::ValueType::Tmp);
|
||||
|
|
@ -1076,10 +1090,17 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
|
|||
info::value::InternalValue(1),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "+=") {
|
||||
// TODO
|
||||
error_handling::HandleInternalError("+= not implemented yet (int)",
|
||||
"ExecuteVisitor.HandleBuiltinTypeFunctionCall",
|
||||
&node->base);
|
||||
*arguments[0]->GetValue<int64_t>().value() += *arguments[1]->GetValue<int64_t>().value();
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "-=") {
|
||||
*arguments[0]->GetValue<int64_t>().value() += *arguments[1]->GetValue<int64_t>().value();
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
} else if (name == "*=") {
|
||||
*arguments[0]->GetValue<int64_t>().value() += *arguments[1]->GetValue<int64_t>().value();
|
||||
current_value_ = context_manager_.AddValue(
|
||||
info::value::InternalValue(info::value::Unit()),
|
||||
utils::ValueType::Tmp);
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) {
|
|||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Namespace* node) {
|
||||
context_manager_.EnterContext();
|
||||
|
||||
if (node->link_typeclass_id_.has_value()) {
|
||||
utils::IdType graph_id = global_info_.GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_;
|
||||
|
||||
context_manager_.EnterContext();
|
||||
|
||||
utils::IdType abstract_type = AddGraphIdLocalAbstractTypes(graph_id);
|
||||
abstract_type = context_manager_.ToModifiedValue(abstract_type,
|
||||
ClassInternalsModifierToValueType(node->modifier));
|
||||
|
|
@ -67,11 +67,10 @@ void TypeCheckVisitor::Visit(Namespace* node) {
|
|||
ClassInternalsModifierToValueType(node->modifier));
|
||||
|
||||
if (node->modifier != utils::ClassInternalsModifier::Static) {
|
||||
context_manager_.EnterVariableContext(utils::ClassInternalVarName, type);
|
||||
} else {
|
||||
context_manager_.EnterContext();
|
||||
context_manager_.DefineVariable(utils::ClassInternalVarName, type);
|
||||
}
|
||||
|
||||
type = context_manager_.ToModifiedValue(type, utils::ValueType::Tmp);
|
||||
AddGraphIdLocalTypes(type_info->type.node->graph_id_, type);
|
||||
|
||||
if (type_namespaces_.count(node->link_type_id_.value()) != 0) {
|
||||
|
|
@ -106,16 +105,12 @@ void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) {
|
|||
&node->base);
|
||||
}
|
||||
|
||||
// TODO: move, etc.
|
||||
void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
|
||||
// TODO: remove variable on move
|
||||
is_in_statement_ = true;
|
||||
|
||||
Visitor::Visit(node->value);
|
||||
// current_type from value automatically passed to name definitions
|
||||
if (node->assignment_modifier == utils::AssignmentModifier::Assign) {
|
||||
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
|
||||
// TODO: make type tmp recursively ??
|
||||
}
|
||||
|
||||
is_const_definition_ = node->modifier;
|
||||
Visitor::Visit(node->name);
|
||||
|
|
@ -127,7 +122,7 @@ void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
|
|||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
|
||||
void TypeCheckVisitor::Visit(FunctionDeclaration* node) { // function declaration check needed ??
|
||||
bool was_in_statement = is_in_statement_;
|
||||
is_in_statement_ = true;
|
||||
|
||||
|
|
@ -141,7 +136,7 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
|
|||
}
|
||||
|
||||
context_manager_.EnterContext();
|
||||
for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed??
|
||||
for (auto& parameter : node->parameters) {
|
||||
current_type_ = context_manager_.AddValue(
|
||||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
||||
parameter->graph_id_,
|
||||
|
|
@ -212,7 +207,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
&node->base);
|
||||
}
|
||||
|
||||
declaration = maybe_function_info.value()->declaration; // TODO: save declaration to global info ??
|
||||
declaration = maybe_function_info.value()->declaration;
|
||||
}
|
||||
|
||||
context_manager_.EnterContext();
|
||||
|
|
@ -233,7 +228,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
|
||||
for (size_t i = 0; i < node->definition->arguments.size(); ++i) {
|
||||
Visitor::Visit(declaration->type->types[i]);
|
||||
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const); // TODO: Var??
|
||||
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const);
|
||||
if (!context_manager_.DefineVariable(node->definition->arguments[i], current_type_)) {
|
||||
error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition", node->base);
|
||||
}
|
||||
|
|
@ -277,7 +272,7 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
|
|||
std::string& type_name = node->definition->type->type;
|
||||
|
||||
for (auto& function : required_functions) {
|
||||
if (function.second.definition.has_value()) { // TODO: check
|
||||
if (function.second.definition.has_value()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -326,9 +321,11 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
|||
|
||||
is_in_statement_ = false;
|
||||
|
||||
// --- can't work always, because "visit" can be called for internal types
|
||||
// current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
|
||||
// node->base.type_ = current_type_;
|
||||
// otherwise function called from VisitSourceFile
|
||||
if (!maybe_internal_type.has_value()) {
|
||||
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
|
||||
node->base.type_ = current_type_;
|
||||
}
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
|
|
@ -376,8 +373,7 @@ void TypeCheckVisitor::Visit(AnyAnnotatedType* node) {
|
|||
|
||||
void TypeCheckVisitor::Visit(TypeConstructorPatternParameter*) {} // Handled in TypeConstructorPattern
|
||||
|
||||
// TODO
|
||||
// TODO: check for tuples
|
||||
// TODO: check ??
|
||||
void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match named constructor
|
||||
if (!node->constructor->constructor_id_.has_value()) {
|
||||
error_handling::HandleTypecheckError("Type constructor pattern constructor name not found", node->base);
|
||||
|
|
@ -450,7 +446,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name
|
|||
|
||||
void TypeCheckVisitor::Visit(MatchCase* node) {
|
||||
// value type passed as current_type_
|
||||
is_const_definition_ = utils::IsConstModifier::Const; // TODO: or var??
|
||||
is_const_definition_ = utils::IsConstModifier::Const;
|
||||
Visitor::Visit(node->value);
|
||||
|
||||
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
|
||||
|
|
@ -473,7 +469,8 @@ void TypeCheckVisitor::Visit(MatchCase* node) {
|
|||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
|
||||
// TODO: move, etc.
|
||||
void TypeCheckVisitor::Visit(Match* node) {
|
||||
// TODO: types can be different in block statement
|
||||
context_manager_.EnterContext();
|
||||
|
||||
|
|
@ -484,9 +481,8 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
|
|||
Visitor::Visit(node->value);
|
||||
utils::IdType value_type = current_type_;
|
||||
|
||||
// TODO: several matches with one statement typecheck <- check proposed solution
|
||||
std::optional<Expression*> nearest_statement;
|
||||
for (ssize_t i = (ssize_t)node->matches.size() - 1; i >= 0; --i) { // TODO: internal contexts ??
|
||||
for (ssize_t i = (ssize_t)node->matches.size() - 1; i >= 0; --i) {
|
||||
ResetReturnedAndBroughtTypes();
|
||||
|
||||
current_type_ = value_type;
|
||||
|
|
@ -570,7 +566,7 @@ void TypeCheckVisitor::Visit(Condition* node) {
|
|||
} else {
|
||||
current_type_ = context_manager_.AddValue(
|
||||
info::type::OptionalType(type, context_manager_.GetValueManager()),
|
||||
utils::ValueType::Tmp); // ??
|
||||
context_manager_.GetValueType(type)); // optional with "reference" to result type
|
||||
}
|
||||
|
||||
context_manager_.ExitContext();
|
||||
|
|
@ -616,6 +612,7 @@ void TypeCheckVisitor::Visit(WhileLoop* node) {
|
|||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
// TODO: variable with reference to interval element + check
|
||||
void TypeCheckVisitor::Visit(ForLoop* node) {
|
||||
context_manager_.EnterContext();
|
||||
|
||||
|
|
@ -707,7 +704,7 @@ void TypeCheckVisitor::Visit(ReferenceExpression* node) {
|
|||
info::type::ReferenceToType({node->reference},
|
||||
current_type_,
|
||||
context_manager_.GetValueManager()),
|
||||
context_manager_.GetValueType(current_type_)); // ??
|
||||
context_manager_.GetValueType(current_type_));
|
||||
}
|
||||
|
||||
// TODO: redifinitions for other types and tuples (with const index) ??
|
||||
|
|
@ -723,7 +720,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
|
|||
auto maybe_type_value = context_manager_.GetValue<info::type::ArrayType>(current_type_);
|
||||
|
||||
if (maybe_type_value.has_value()) {
|
||||
current_type_ = maybe_type_value.value()->GetElementsType();
|
||||
current_type_ = maybe_type_value.value()->GetElementsType(); // "reference" to element
|
||||
} else {
|
||||
auto maybe_internal_type_value = context_manager_.GetValue<info::type::InternalType>(current_type_);
|
||||
|
||||
|
|
@ -740,7 +737,6 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
|
|||
|
||||
// Other Expressions
|
||||
|
||||
// TODO: more builtin functions, better handling (??)
|
||||
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||
context_manager_.EnterContext();
|
||||
|
||||
|
|
@ -842,7 +838,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
Visitor::Visit(function_declaration->type->types.back());
|
||||
current_type_ = TypeInContext(current_type_, context);
|
||||
|
||||
node->base.type_ = current_type_;
|
||||
node->base.type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TupleExpression* node) {
|
||||
|
|
@ -916,6 +912,7 @@ void TypeCheckVisitor::Visit(ReturnExpression* node) {
|
|||
void TypeCheckVisitor::Visit(TypeConstructorParameter*) {} // Handeled in TypeConstructor visit
|
||||
|
||||
// TODO: check for tuples
|
||||
// TODO: move, etc.
|
||||
void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
||||
if (!node->constructor->constructor_id_.has_value()) {
|
||||
error_handling::HandleTypecheckError("Type constructor name not found", node->base);
|
||||
|
|
@ -929,7 +926,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
|||
|
||||
utils::IdType constructor_id = node->constructor->constructor_id_.value();
|
||||
|
||||
// TODO: take type_id_ ??
|
||||
info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id);
|
||||
|
||||
utils::IdType type_id = constructor_info.type_id;
|
||||
|
|
@ -940,7 +936,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
|||
std::optional<info::definition::AnyType*> maybe_type_info =
|
||||
global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
|
||||
|
||||
if (!maybe_type_info.has_value()) { // TODO
|
||||
if (!maybe_type_info.has_value()) {
|
||||
error_handling::HandleInternalError("Implemented only for AnyType",
|
||||
"TypeCheckVisitor.TypeConstructor",
|
||||
&node->base);
|
||||
|
|
@ -957,7 +953,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < node->parameters.size(); ++i) {
|
||||
// TODO: remove variable on move
|
||||
if (node->parameters[i].name.has_value()) {
|
||||
if (!constructor_fields->entities[i].first.has_value()
|
||||
|| constructor_fields->entities[i].first.value() != node->parameters[i].name.value()) {
|
||||
|
|
@ -1088,6 +1083,7 @@ void TypeCheckVisitor::Visit(NameExpression* node) {
|
|||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
// TODO: move, etc.
|
||||
void TypeCheckVisitor::Visit(TupleName* node) {
|
||||
utils::IdType type = current_type_;
|
||||
|
||||
|
|
@ -1113,15 +1109,11 @@ void TypeCheckVisitor::Visit(TupleName* node) {
|
|||
}
|
||||
|
||||
utils::ValueType value_type = context_manager_.GetValueType(type);
|
||||
if (value_type == utils::ValueType::Const
|
||||
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
|
||||
error_handling::HandleTypecheckError("TupleName: value type expression not match variable definition modifier", node->base);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
current_type_ = type_value->GetFields()[i].second;
|
||||
|
||||
if (value_type == utils::ValueType::Tmp) { // TODO: ??
|
||||
if (value_type == utils::ValueType::Tmp) { // TODO: instead of recusive modification ??
|
||||
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
|
|
@ -1133,6 +1125,7 @@ void TypeCheckVisitor::Visit(TupleName* node) {
|
|||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
// TODO: move, etc.
|
||||
void TypeCheckVisitor::Visit(VariantName* node) {
|
||||
utils::IdType type = current_type_;
|
||||
|
||||
|
|
@ -1157,12 +1150,6 @@ void TypeCheckVisitor::Visit(VariantName* node) {
|
|||
&node->base);
|
||||
}
|
||||
|
||||
utils::ValueType value_type = context_manager_.GetValueType(type);
|
||||
if (value_type == utils::ValueType::Const
|
||||
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
|
||||
error_handling::HandleTypecheckError("VariantName: value type of type and value type are different", node->base);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
if (type_value->GetConstructors()[i].GetFields().empty()) {
|
||||
current_type_ = context_manager_.AddValue(
|
||||
|
|
@ -1189,6 +1176,7 @@ void TypeCheckVisitor::Visit(VariantName* node) {
|
|||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
// TODO: move, etc.
|
||||
void TypeCheckVisitor::Visit(AnnotatedName* node) {
|
||||
utils::IdType type = current_type_;
|
||||
|
||||
|
|
@ -1198,12 +1186,6 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
|
|||
&node->base);
|
||||
}
|
||||
|
||||
utils::ValueType value_type = context_manager_.GetValueType(type);
|
||||
if (value_type == utils::ValueType::Const
|
||||
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
|
||||
error_handling::HandleTypecheckError("AnnotatedName: value type expression not match variable definition modifier", node->base);
|
||||
}
|
||||
|
||||
type = context_manager_.ToModifiedValue(type, utils::IsConstModifierToValueType(is_const_definition_.value()));
|
||||
if (!context_manager_.DefineVariable(node->name, type)) {
|
||||
error_handling::HandleTypecheckError("Variable name already present in context", node->base);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue