mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
typecheck refactoring start
This commit is contained in:
parent
0088f2b4e3
commit
00bf9705a9
2 changed files with 85 additions and 70 deletions
|
|
@ -11,10 +11,11 @@
|
||||||
|
|
||||||
namespace type_check {
|
namespace type_check {
|
||||||
|
|
||||||
class ContextHolder;
|
template <nodes::Return::Kind kind> class ContextHolder;
|
||||||
|
|
||||||
class State {
|
class State {
|
||||||
friend ContextHolder;
|
friend ContextHolder<nodes::Return::Kind::BRING>;
|
||||||
|
friend ContextHolder<nodes::Return::Kind::RETURN>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct VariableInfo {
|
struct VariableInfo {
|
||||||
|
|
@ -92,7 +93,7 @@ private:
|
||||||
// TODO: argument for property is returned type should be merged
|
// TODO: argument for property is returned type should be merged
|
||||||
// returns brought type, return type is merged with next context or with
|
// returns brought type, return type is merged with next context or with
|
||||||
// brought type in last context
|
// brought type in last context
|
||||||
nodes::MaybeType exit_context() {
|
nodes::MaybeType ExitContext(nodes::Return::Kind result_kind) {
|
||||||
Log::Context logc(log_, Log::Area::kTypeCheck);
|
Log::Context logc(log_, Log::Area::kTypeCheck);
|
||||||
|
|
||||||
if (contexts_.empty()) {
|
if (contexts_.empty()) {
|
||||||
|
|
@ -129,7 +130,14 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return brought_type;
|
switch (result_kind) {
|
||||||
|
case nodes::Return::Kind::BRING:
|
||||||
|
return brought_type;
|
||||||
|
case nodes::Return::Kind::RETURN:
|
||||||
|
return returned_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -239,7 +247,7 @@ private:
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
class ContextHolder {
|
template <nodes::Return::Kind kind> class ContextHolder {
|
||||||
public:
|
public:
|
||||||
ContextHolder(State &state, const utils::Pos &pos,
|
ContextHolder(State &state, const utils::Pos &pos,
|
||||||
nodes::MaybeType *context_exit_type)
|
nodes::MaybeType *context_exit_type)
|
||||||
|
|
@ -255,9 +263,9 @@ public:
|
||||||
|
|
||||||
~ContextHolder() {
|
~ContextHolder() {
|
||||||
if (context_exit_type_) {
|
if (context_exit_type_) {
|
||||||
*context_exit_type_ = state_.exit_context();
|
*context_exit_type_ = state_.ExitContext(kind);
|
||||||
} else {
|
} else {
|
||||||
state_.exit_context();
|
state_.ExitContext(kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,18 +148,16 @@ Result CheckTask<nodes::Condition>::operator()(const nodes::Condition &expr,
|
||||||
return TypeCheckFromArgs(expr_result.value().Get(), args, current_pos);
|
return TypeCheckFromArgs(expr_result.value().Get(), args, current_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: change to ranges in future
|
||||||
Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
|
Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
|
||||||
const Args &args) {
|
const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
const auto current_pos = PosOf(args.current_id);
|
const auto current_pos = PosOf(args.current_id);
|
||||||
|
|
||||||
// TODO: ranges ??
|
//
|
||||||
|
|
||||||
MaybeResult interval_result;
|
MaybeResult interval_result;
|
||||||
|
|
||||||
MaybeResult variable_result;
|
MaybeResult variable_result;
|
||||||
|
|
||||||
Result expression_result = Run(expr.expr, {expr.expr});
|
Result expression_result = Run(expr.expr, {expr.expr});
|
||||||
|
|
||||||
switch (expr.kind) {
|
switch (expr.kind) {
|
||||||
|
|
@ -168,74 +166,67 @@ Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
|
||||||
case nodes::Loop::WHILE:
|
case nodes::Loop::WHILE:
|
||||||
Run(expr.condition.value(), Args{expr.condition.value()}.ExpectBuiltin(
|
Run(expr.condition.value(), Args{expr.condition.value()}.ExpectBuiltin(
|
||||||
builtin::Type::BOOL, executor));
|
builtin::Type::BOOL, executor));
|
||||||
|
|
||||||
// --- type check is independent from loop itself ---
|
|
||||||
// if (condition_result.value().is_invalid()) {
|
|
||||||
// return condition_result.value();
|
|
||||||
// }
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case nodes::Loop::FOR:
|
case nodes::Loop::FOR:
|
||||||
// TODO: expect range ??
|
|
||||||
interval_result =
|
interval_result =
|
||||||
Run(expr.interval.value(), Args{expr.interval.value()}.ExpectBuiltin(
|
Run(expr.interval.value(),
|
||||||
builtin::Type::ARRAY, executor));
|
Args{expr.interval.value()}.ExpectBuiltin(
|
||||||
|
builtin::Type::ARRAY /* NOTE: range in future */, executor));
|
||||||
|
|
||||||
if (interval_result.value().is_invalid()) {
|
if (interval_result.value().is_invalid()) {
|
||||||
// --- type check is independent from loop itself ---
|
|
||||||
// return interval_result.value();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
variable_result =
|
const auto range_elem_type =
|
||||||
Run(expr.variable.value(),
|
interval_result.value().Get().get()->get_parameter_proxy(0);
|
||||||
Args{expr.variable.value()}.Expect(
|
|
||||||
interval_result.value().Get().get()->get_parameter_proxy(0)));
|
|
||||||
|
|
||||||
// --- type check is independent from loop itself ---
|
variable_result = Run(expr.variable.value(),
|
||||||
// if (variable_result.value().is_invalid()) {
|
Args{expr.variable.value()}.Expect(
|
||||||
// return variable_result.value();
|
range_elem_type)); // TODO: or pass type ??
|
||||||
// }
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression_result.is_invalid()) { // TODO: log invalid
|
if (expression_result.is_invalid()) {
|
||||||
return expression_result;
|
TypeCheckError("Invalid loop expression", PosOf(expr.expr));
|
||||||
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: modifier checks ??, modifiers ??
|
|
||||||
|
|
||||||
return TypeCheckFromArgs(state<Types>().add_array_of(expression_result.Get()),
|
return TypeCheckFromArgs(state<Types>().add_array_of(expression_result.Get()),
|
||||||
args, current_pos);
|
args, current_pos);
|
||||||
} // IN PROGRESS
|
}
|
||||||
|
|
||||||
// --- containers
|
// --- containers
|
||||||
|
|
||||||
Result CheckTask<nodes::Container>::CheckArray(const nodes::Container &expr,
|
Result CheckTask<nodes::Container>::CheckArray(const nodes::Container &expr,
|
||||||
const Args &args) {
|
const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
const auto current_pos = PosOf(args.current_id);
|
const auto current_pos = PosOf(args.current_id);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
MaybeResult last_expr_result;
|
MaybeResult last_expr_result;
|
||||||
|
|
||||||
for (const auto &elem_expr : expr.exprs) {
|
for (const auto &elem_expr : expr.exprs) {
|
||||||
// elements should have same type, but type is not expected
|
// elements should have the same type, but no type expected
|
||||||
auto expr_result = Run(elem_expr, {elem_expr});
|
auto expr_result = Run(elem_expr, {elem_expr});
|
||||||
|
|
||||||
if (!last_expr_result.has_value()) {
|
if (expr_result.is_invalid()) {
|
||||||
|
TypeCheckError("Invalid array element", PosOf(args.current_id));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not last_expr_result.has_value()) {
|
||||||
last_expr_result = expr_result;
|
last_expr_result = expr_result;
|
||||||
} else {
|
} else {
|
||||||
if (last_expr_result.value().Get() != expr_result.Get()) {
|
if (last_expr_result.value().Get() != expr_result.Get()) {
|
||||||
TypeCheckError("Elements in array should have same type",
|
TypeCheckError("Elements in array should have same type",
|
||||||
PosOf(args.current_id));
|
PosOf(args.current_id));
|
||||||
// return TypeCheckResult::construct_invalid_result(); // max
|
// type is not modified to max possible type deduction
|
||||||
// possible checks, so no return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!last_expr_result.has_value()) {
|
if (not last_expr_result.has_value()) {
|
||||||
TypeCheckError("Array with zero elements", current_pos);
|
TypeCheckError("Array with zero elements", current_pos);
|
||||||
return Result::invalid();
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
|
|
@ -248,15 +239,16 @@ Result CheckTask<nodes::Container>::CheckArray(const nodes::Container &expr,
|
||||||
Result CheckTask<nodes::Container>::CheckBlock(const nodes::Container &expr,
|
Result CheckTask<nodes::Container>::CheckBlock(const nodes::Container &expr,
|
||||||
const Args &args) {
|
const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
const auto current_pos = PosOf(args.current_id);
|
const auto current_pos = PosOf(args.current_id);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
nodes::MaybeType context_exit_type;
|
nodes::MaybeType context_exit_type;
|
||||||
|
|
||||||
{
|
{
|
||||||
ContextHolder context_holder(
|
// brought type returned
|
||||||
state<State>(), current_pos,
|
ContextHolder<nodes::Return::Kind::BRING> context_holder(
|
||||||
&context_exit_type); // TODO: is brought type returned
|
state<State>(), current_pos, &context_exit_type);
|
||||||
|
|
||||||
for (const auto &elem_expr : expr.exprs) {
|
for (const auto &elem_expr : expr.exprs) {
|
||||||
// result types in block are discarded
|
// result types in block are discarded
|
||||||
|
|
@ -269,8 +261,7 @@ Result CheckTask<nodes::Container>::CheckBlock(const nodes::Container &expr,
|
||||||
? Result(context_exit_type.value())
|
? Result(context_exit_type.value())
|
||||||
: Result(state<Types>().primitive(builtin::Type::UNIT));
|
: Result(state<Types>().primitive(builtin::Type::UNIT));
|
||||||
|
|
||||||
return TypeCheckFromArgs(
|
return TypeCheckFromArgs(block_brought_type.Get(), args, current_pos);
|
||||||
state<Types>().add_array_of(block_brought_type.Get()), args, current_pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheckTask<nodes::Container>::operator()(const nodes::Container &expr,
|
Result CheckTask<nodes::Container>::operator()(const nodes::Container &expr,
|
||||||
|
|
@ -288,24 +279,25 @@ Result CheckTask<nodes::Container>::operator()(const nodes::Container &expr,
|
||||||
Result CheckTask<nodes::Return>::operator()(const nodes::Return &expr,
|
Result CheckTask<nodes::Return>::operator()(const nodes::Return &expr,
|
||||||
const Args &args) {
|
const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
const auto current_pos = PosOf(args.current_id);
|
const auto current_pos = PosOf(args.current_id);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
auto returned_result = Run(expr.expr, {expr.expr});
|
auto returned_result = Run(expr.expr, {expr.expr});
|
||||||
|
|
||||||
if (returned_result.is_invalid()) {
|
if (returned_result.is_invalid()) {
|
||||||
return returned_result;
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (expr.kind) {
|
switch (expr.kind) {
|
||||||
case nodes::Return::BRING:
|
case nodes::Return::BRING:
|
||||||
if (state<State>().BringType(returned_result.Get())) {
|
if (not state<State>().BringType(returned_result.Get())) {
|
||||||
TypeCheckError("Different brought type to current one", current_pos);
|
TypeCheckError("Different brought type to current one", current_pos);
|
||||||
return Result::invalid();
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case nodes::Return::RETURN:
|
case nodes::Return::RETURN:
|
||||||
if (!state<State>().ReturnType(returned_result.Get())) {
|
if (not state<State>().ReturnType(returned_result.Get())) {
|
||||||
TypeCheckError("Different returned type to current one", current_pos);
|
TypeCheckError("Different returned type to current one", current_pos);
|
||||||
return Result::invalid();
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
|
|
@ -316,6 +308,8 @@ Result CheckTask<nodes::Return>::operator()(const nodes::Return &expr,
|
||||||
current_pos);
|
current_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <------ NOTE: CHECK ENDED THERE
|
||||||
|
|
||||||
// TODO: warning if name is same to package prefix, function prefix, etc. ??
|
// TODO: warning if name is same to package prefix, function prefix, etc. ??
|
||||||
Result
|
Result
|
||||||
CheckTask<nodes::NameDefinition>::operator()(const nodes::NameDefinition &expr,
|
CheckTask<nodes::NameDefinition>::operator()(const nodes::NameDefinition &expr,
|
||||||
|
|
@ -351,46 +345,51 @@ CheckTask<nodes::NameDefinition>::operator()(const nodes::NameDefinition &expr,
|
||||||
current_pos);
|
current_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: CHECKED
|
||||||
Result CheckTask<nodes::Access>::CheckArrayAccess(const nodes::Access &expr,
|
Result CheckTask<nodes::Access>::CheckArrayAccess(const nodes::Access &expr,
|
||||||
const Args &args) {
|
const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
const auto current_pos = PosOf(args.current_id);
|
const auto current_pos = PosOf(args.current_id);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
auto index_result =
|
auto index_result =
|
||||||
Run(expr.index,
|
Run(expr.index,
|
||||||
Args{expr.index}.ExpectBuiltin(builtin::Type::INDEX, executor));
|
Args{expr.index}.ExpectBuiltin(builtin::Type::INDEX, executor));
|
||||||
|
|
||||||
|
// TODO: check expect for parametrized type without parametears
|
||||||
auto value_result =
|
auto value_result =
|
||||||
Run(expr.value,
|
Run(expr.value,
|
||||||
Args{expr.value}.ExpectBuiltin(builtin::Type::ARRAY, executor));
|
Args{expr.value}.ExpectBuiltin(builtin::Type::ARRAY, executor));
|
||||||
|
|
||||||
if (index_result.is_invalid()) {
|
if (index_result.is_invalid()) {
|
||||||
return index_result;
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value_result.is_invalid()) {
|
if (value_result.is_invalid()) {
|
||||||
return value_result;
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: modifier checks ??
|
// NOTE: 0 - type of array
|
||||||
|
|
||||||
return TypeCheckFromArgs(value_result.Get().get()->get_parameter_proxy(0),
|
return TypeCheckFromArgs(value_result.Get().get()->get_parameter_proxy(0),
|
||||||
args, current_pos);
|
args, current_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: CHECKED
|
||||||
Result CheckTask<nodes::Access>::CheckTupleAccess(const nodes::Access &expr,
|
Result CheckTask<nodes::Access>::CheckTupleAccess(const nodes::Access &expr,
|
||||||
const Args &args) {
|
const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
const auto current_pos = PosOf(args.current_id);
|
const auto current_pos = PosOf(args.current_id);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// TODO: check expect for parametrized type without parametears
|
||||||
auto value_result =
|
auto value_result =
|
||||||
Run(expr.value,
|
Run(expr.value,
|
||||||
Args{expr.value}.ExpectBuiltin(builtin::Type::TUPLE, executor));
|
Args{expr.value}.ExpectBuiltin(builtin::Type::TUPLE, executor));
|
||||||
|
|
||||||
if (value_result.is_invalid()) {
|
if (value_result.is_invalid()) {
|
||||||
return value_result;
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t index = *Ext(expr.index)
|
size_t index = *Ext(expr.index)
|
||||||
|
|
@ -398,12 +397,11 @@ Result CheckTask<nodes::Access>::CheckTupleAccess(const nodes::Access &expr,
|
||||||
.get<size_t>() // Index type
|
.get<size_t>() // Index type
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
// TODO: modifier checks ??
|
|
||||||
|
|
||||||
return TypeCheckFromArgs(value_result.Get().get()->get_parameter_proxy(index),
|
return TypeCheckFromArgs(value_result.Get().get()->get_parameter_proxy(index),
|
||||||
args, current_pos);
|
args, current_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: CHECKED
|
||||||
Result CheckTask<nodes::Access>::operator()(const nodes::Access &expr,
|
Result CheckTask<nodes::Access>::operator()(const nodes::Access &expr,
|
||||||
const Args &args) {
|
const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
@ -416,12 +414,14 @@ Result CheckTask<nodes::Access>::operator()(const nodes::Access &expr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: CHECKED
|
||||||
Result CheckTask<nodes::LoopControl>::operator()(const nodes::LoopControl &expr,
|
Result CheckTask<nodes::LoopControl>::operator()(const nodes::LoopControl &expr,
|
||||||
const Args &args) {
|
const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
const auto current_pos = PosOf(args.current_id);
|
const auto current_pos = PosOf(args.current_id);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
return TypeCheckFromArgs(state<Types>().primitive(builtin::Type::UNIT), args,
|
return TypeCheckFromArgs(state<Types>().primitive(builtin::Type::UNIT), args,
|
||||||
current_pos);
|
current_pos);
|
||||||
}
|
}
|
||||||
|
|
@ -429,28 +429,27 @@ Result CheckTask<nodes::LoopControl>::operator()(const nodes::LoopControl &expr,
|
||||||
Result CheckTask<nodes::ModifierExpression>::operator()(
|
Result CheckTask<nodes::ModifierExpression>::operator()(
|
||||||
const nodes::ModifierExpression &expr, const Args &args) {
|
const nodes::ModifierExpression &expr, const Args &args) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
const auto current_pos = PosOf(args.current_id);
|
const auto current_pos = PosOf(args.current_id);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// TODO: expext Optional or Result ??
|
||||||
auto modified_result = Run(expr.expr, {expr.expr});
|
auto modified_result = Run(expr.expr, {expr.expr});
|
||||||
|
|
||||||
if (modified_result.is_invalid()) {
|
if (modified_result.is_invalid()) {
|
||||||
return Result::invalid();
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodes::utils::is_suffix_modifier(
|
if (nodes::utils::is_suffix_modifier(expr.modifier)) { // optional, result
|
||||||
expr.modifier)) { // optional, result
|
|
||||||
// '?' - open optional / result in ->
|
// '?' - open optional / result in -> (execute or not execute pattern
|
||||||
// (execute or not execute pattern
|
// matching expression) / (value / return) (TODO: alternative for bring)
|
||||||
// matching expression) / (value /
|
|
||||||
// return) (TODO: alternative for bring)
|
|
||||||
|
|
||||||
// '!' - open optional / result -> value / panic
|
// '!' - open optional / result -> value / panic
|
||||||
|
|
||||||
switch (modified_result.Get().get()->to_builtin()) {
|
switch (modified_result.Get().get()->to_builtin()) {
|
||||||
case builtin::Type::OPTIONAL:
|
case builtin::Type::OPTIONAL:
|
||||||
case builtin::Type::RESULT:
|
case builtin::Type::RESULT:
|
||||||
// TODO: how to unwrap external modifier ??
|
|
||||||
modified_result.Set(modified_result.Get().get()->get_parameter_proxy(0));
|
modified_result.Set(modified_result.Get().get()->get_parameter_proxy(0));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -458,7 +457,9 @@ Result CheckTask<nodes::ModifierExpression>::operator()(
|
||||||
return Result::invalid();
|
return Result::invalid();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: check that modifier can be applied
|
// NOTE: other modifiers applied instead of current one
|
||||||
|
|
||||||
|
// TODO: check thatmodification is possible
|
||||||
modified_result.Set(state<Types>().add_modification_of(
|
modified_result.Set(state<Types>().add_modification_of(
|
||||||
modified_result.Get(), expr.modifier));
|
modified_result.Get(), expr.modifier));
|
||||||
}
|
}
|
||||||
|
|
@ -937,16 +938,22 @@ Result CheckTask<nodes::Lambda>::operator()(const nodes::Lambda &expr,
|
||||||
return TypeCheckFromArgs(expected_type, args, current_pos);
|
return TypeCheckFromArgs(expected_type, args, current_pos);
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
|
// NOTE: CHECKED
|
||||||
Result CheckTask<nodes::Extra>::operator()(const nodes::Extra &, const Args &) {
|
Result CheckTask<nodes::Extra>::operator()(const nodes::Extra &, const Args &) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
return Result(state<Types>().primitive(builtin::Type::UNIT));
|
return Result(state<Types>().primitive(builtin::Type::UNIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: CHECKED
|
||||||
Result CheckTask<nodes::EmptyLines>::operator()(const nodes::EmptyLines &,
|
Result CheckTask<nodes::EmptyLines>::operator()(const nodes::EmptyLines &,
|
||||||
const Args &) {
|
const Args &) {
|
||||||
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
return Result(state<Types>().primitive(builtin::Type::UNIT));
|
return Result(state<Types>().primitive(builtin::Type::UNIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue