diff --git a/include/builtin_functions.hpp b/include/builtin_functions.hpp index 5fba95c..25324de 100644 --- a/include/builtin_functions.hpp +++ b/include/builtin_functions.hpp @@ -9,7 +9,9 @@ namespace info::builtin { template inline void Print(const T& value) { // only for strings ?? - std::cout << "\x1b[1;32mOutput:\x1b[0m " << value << '\n'; + std::cout << "\x1b[1;32mOutput:\x1b[0m "; + std::cout << value; + std::cout << '\n'; } template diff --git a/include/contexts.hpp b/include/contexts.hpp index 6cda970..853701b 100644 --- a/include/contexts.hpp +++ b/include/contexts.hpp @@ -19,6 +19,10 @@ public: contexts_.emplace_back(true); // no difference ?? } + size_t ContextCount() { + return contexts_.size(); + } + template utils::IdType AddValue(const T& value, utils::ValueType value_type) { return value_manager_.AddValue(value, value_type); diff --git a/lang-parser b/lang-parser index ad07e6d..ddb08e9 160000 --- a/lang-parser +++ b/lang-parser @@ -1 +1 @@ -Subproject commit ad07e6d8fb84b902aea295baf0c1c2faccdce849 +Subproject commit ddb08e9b65123324800d1126d38764764363c0e5 diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index ca0a941..7a4219c 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -1525,7 +1525,7 @@ void BuildVisitor::Visit(NumberLiteral* node) { node->value = std::stoll(current_node_.GetValue()); } -void BuildVisitor::Visit(StringLiteral* node) { +void BuildVisitor::Visit(StringLiteral* node) { // TODO: special symbols, etc. SetPosition(node->base, current_node_); std::string literal = current_node_.GetValue(); diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index 0645f66..9f0e74a 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -63,9 +63,14 @@ void ExecuteVisitor::Visit(FunctionDeclaration* node) { void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call context_manager_.EnterContext(); + size_t context_count = context_manager_.ContextCount(); try { Visitor::Visit(node->value); - } catch (utils::ValueReturnedMarker&) {} + } catch (utils::ValueReturnedMarker&) { + while (context_manager_.ContextCount() > context_count) { + context_manager_.ExitContext(); + } + } // TODO: sometimes return references, choose by declaration current_value_ = context_manager_.ToTemporaryValue(current_value_); @@ -345,9 +350,13 @@ void ExecuteVisitor::Visit(Block* node) { bool value_brought = false; for (auto& statement : node->statements) { + size_t context_count = context_manager_.ContextCount(); try { Visitor::Visit(statement); } catch (utils::ValueBroughtMarker&) { // current_value_ passed from ReturnExpression + while (context_manager_.ContextCount() > context_count) { + context_manager_.ExitContext(); + } value_brought = true; break; } @@ -459,7 +468,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); } if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) { - error_handling::HandleRuntimeError("Variable redefinition (mathod caller var)", node->base); + error_handling::HandleRuntimeError("Variable redefinition (self var)", node->base); } } } @@ -481,7 +490,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { if (!maybe_function_definition_info.has_value()) { if (HandleBuiltinFunctionCall(node)) { context_manager_.ExitContext(); - return; + return; // TODO: return from end of function } error_handling::HandleRuntimeError("Function definition not found (by graph_id_)", node->base); @@ -490,7 +499,6 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { function_definition = maybe_function_definition_info.value().node; } else if (node->graph_id_.has_value()) { - error_handling::DebugPrint(typeclass_graph_.GetVertex(node->graph_id_.value()).name); utils::IdType defined_type_graph_id; // try to find defined or basic type if (typeclass_graph_.GetVertex(node->graph_id_.value()).type_id.has_value() @@ -510,7 +518,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { std::optional maybe_function_definition; auto maybe_function_graph_info = typeclass_graph_.GetFunctionInfo(node->name, - node->graph_id_.value()); + defined_type_graph_id); if (!maybe_function_graph_info.has_value()) { error_handling::HandleRuntimeError("Function info not found (by graph_id_)", node->base); @@ -520,8 +528,8 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { maybe_function_definition = maybe_function_graph_info.value()->definition; if (!maybe_function_definition.has_value()) { - if (typeclass_graph_.GetVertex(node->graph_id_.value()).modifier == info::TypeclassGraph::Modifier::Type) { - auto maybe_internal_type = info::type::ToInternalType(typeclass_graph_.GetVertex(node->graph_id_.value()).name); + if (typeclass_graph_.GetVertex(defined_type_graph_id).modifier == info::TypeclassGraph::Modifier::Type) { + auto maybe_internal_type = info::type::ToInternalType(typeclass_graph_.GetVertex(defined_type_graph_id).name); if (maybe_internal_type.has_value()) { if (HandleBuiltinTypeFunctionCall(node, maybe_internal_type.value())) { @@ -533,37 +541,6 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { error_handling::HandleRuntimeError("Type function definition not found (by graph_id_)", node->base); } - - // if (!node->abstract_type_name_.has_value()) { - // error_handling::HandleInternalError("Typeclass function's abstract_type_name_ has no value", - // "ExecuteVisitor.FunctionCallExpression", - // &node->base); - // } - - auto maybe_type_id = typeclass_graph_.GetVertex(defined_type_graph_id).type_id; - - if (!maybe_type_id.has_value()) { - error_handling::HandleInternalError("Function's abstract type type_id not found", - "ExecuteVisitor.FunctionCallExpression", - &node->base); - } - - auto maybe_type_info = global_info_.GetTypeInfo(maybe_type_id.value()); - - if (!maybe_type_info.has_value()) { - error_handling::HandleRuntimeError("Function's abstract type replacement defined type is not AnyType", node->base); - } - - maybe_function_graph_info = typeclass_graph_.GetFunctionInfo(node->name, maybe_type_info.value()->type.node->graph_id_); - - if (!maybe_function_graph_info.has_value()) { - error_handling::HandleRuntimeError("Function info not found (by abstract type graph_id_)", node->base); - } - - maybe_function_definition = maybe_function_graph_info.value()->definition; - } - - if (!maybe_function_definition.has_value()) { error_handling::HandleRuntimeError("Function definition not found (by graph_id_)", node->base); } @@ -1041,8 +1018,16 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, switch (type) { case info::type::InternalType::Float: if (name == "show") { + try { + current_value_ = context_manager_.AddValue( + info::value::InternalValue(std::to_string(*arguments[0]->GetValue().value())), + utils::ValueType::Tmp); + } catch(...) { + error_handling::HandleRuntimeError("Can't read Float", node->base); + } + } else if (name == "read") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::to_string(*arguments[0]->GetValue().value())), + info::value::InternalValue(std::stod(*arguments[0]->GetValue().value())), utils::ValueType::Tmp); } else if (name == "<") { current_value_ = context_manager_.AddValue( @@ -1094,6 +1079,14 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, current_value_ = context_manager_.AddValue( info::value::InternalValue(std::to_string(*arguments[0]->GetValue().value())), utils::ValueType::Tmp); + } else if (name == "read") { + try { + current_value_ = context_manager_.AddValue( + info::value::InternalValue(std::stoi(*arguments[0]->GetValue().value())), + utils::ValueType::Tmp); + } catch(...) { + error_handling::HandleRuntimeError("Can't read Int", node->base); + } } else if (name == "<") { current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value() < *arguments[1]->GetValue().value()), @@ -1147,6 +1140,10 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value()), utils::ValueType::Tmp); + } else if (name == "read") { // do not copy ?? + current_value_ = context_manager_.AddValue( + info::value::InternalValue(*arguments[0]->GetValue().value()), + utils::ValueType::Tmp); } else if (name == "<") { current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value() < *arguments[1]->GetValue().value()), @@ -1177,6 +1174,14 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, current_value_ = context_manager_.AddValue( info::value::InternalValue(std::string{*arguments[0]->GetValue().value()}), utils::ValueType::Tmp); + } else if (name == "read") { + if (arguments[0]->GetValue().value()->size() != 1) { + error_handling::HandleRuntimeError("Can't read Char", node->base); + } else { + current_value_ = context_manager_.AddValue( + info::value::InternalValue((*arguments[0]->GetValue().value())[0]), + utils::ValueType::Tmp); + } } else if (name == "<") { current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value() < *arguments[1]->GetValue().value()), @@ -1199,6 +1204,18 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value() ? "true" : "false"), utils::ValueType::Tmp); + } else if (name == "read") { + if (*arguments[0]->GetValue().value() == "true") { + current_value_ = context_manager_.AddValue( + info::value::InternalValue(true), + utils::ValueType::Tmp); + } else if (*arguments[0]->GetValue().value() == "false") { + current_value_ = context_manager_.AddValue( + info::value::InternalValue(false), + utils::ValueType::Tmp); + } else { + error_handling::HandleRuntimeError("Can't read Bool", node->base); + } } else if (name == "=") { *arguments[0]->GetValue().value() = *arguments[1]->GetValue().value(); current_value_ = context_manager_.AddValue( @@ -1213,6 +1230,13 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, current_value_ = context_manager_.AddValue( info::value::InternalValue("()"), utils::ValueType::Tmp); + } else if (name == "read") { + if (*arguments[0]->GetValue().value() != "()") { + error_handling::HandleRuntimeError("Can't read Unit", node->base); + } + current_value_ = context_manager_.AddValue( + info::value::InternalValue(info::value::Unit()), + utils::ValueType::Tmp); } else if (name == "=") { current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), diff --git a/src/main.cpp b/src/main.cpp index 9d73e0c..6b4a7d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -72,6 +72,8 @@ int main(int argc, char** argv) { // TODO, only test version const info::GlobalInfo::PartitionInfo& main_partition = global_info.GetPartitionInfo(maybe_main_partition_id.value()); + std::cout << "\n---------------------------------- Execution -------------------------------------\n\n"; + interpreter::ExecuteVisitor execute_visitor(global_info, type_context_manager, context_manager); diff --git a/src/utils.cpp b/src/utils.cpp index e9dbdd6..1bbebd1 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -35,8 +35,8 @@ ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier) { bool IsBuiltinFunction(const std::string& name) { // optimize ?? std::unordered_set builtin_functions; - builtin_functions.insert("="); - builtin_functions.insert("<-"); + builtin_functions.insert("="); // TODO: for all types + // builtin_functions.insert("<-"); // TODO builtin_functions.insert("=="); builtin_functions.insert("<"); builtin_functions.insert("+="); @@ -52,7 +52,7 @@ bool IsBuiltinFunction(const std::string& name) { // optimize ?? builtin_functions.insert("zero"); builtin_functions.insert("one"); builtin_functions.insert("show"); - // builtin_functions.insert("read"); // TODO + builtin_functions.insert("read"); // builtin_functions.insert("debug_show"); // TODO return builtin_functions.count(name) != 0; diff --git a/tests/test_code.lang b/tests/test_code.lang index 04a8ecf..191d028 100644 --- a/tests/test_code.lang +++ b/tests/test_code.lang @@ -1,9 +1,9 @@ -basic (Float : #Ord #Div #Show) -basic (Int : #Ord #IDiv #Show) -basic (String : #Ord #Show #CharContainer #Copy) -basic (Char : #Ord #Show #Copy) -basic (Bool : #Ord #Show #Copy) -basic (Unit : #Show #Copy) +basic (Float : #Ord #Div #Str) +basic (Int : #Ord #IDiv #Str) +basic (String : #Ord #Str #CharContainer #Copy) +basic (Char : #Ord #Str #Copy) +basic (Bool : #Ord #Str #Copy) +basic (Unit : #Str #Copy) // @@ -148,8 +148,10 @@ namespace var Ord { typeclass Show = & var show : -> String -// typeclass Read = // TODO -// & var read : String -> Read +typeclass Read = + & var read : String -> Read + +typeclass (Str : #Show #Read) // typeclass DebugShow = // TODO // & debug_show : -> String @@ -205,20 +207,20 @@ def ( -- ) : begin end = { var current = begin return (while current < end do { ; current += 1 - bring current - //bring current - 1 + bring current - 1 }) } decl func : String -> Int -> Int def func : s i = { ; print: s + var x = s ; print: (i.show:) return 5 } exec main { - for i in 0--9 do func: "abacaba" (i - 1) + for i in 0--19 do func: "a" (i * 2 +. 3) ; print: ({ if true then bring scan: else { ; print: "aaa" } bring "nothing"