diff --git a/examples/args.funk b/examples/args.funk new file mode 100644 index 0000000000000000000000000000000000000000..ba06c4d89ad7488bfb4fff78eefb59eb29c1606a --- /dev/null +++ b/examples/args.funk @@ -0,0 +1,2 @@ +print("A list of arguments with length: ", ARGS.length()); +print("The arguments are:", ARGS); diff --git a/include/ast/expression/MethodCallNode.h b/include/ast/expression/MethodCallNode.h index 52427452ff81c17d9837fdbbfce47106815e036c..220a8f49ac02e2432a0e6cfbf6daec8dd423ef72 100644 --- a/include/ast/expression/MethodCallNode.h +++ b/include/ast/expression/MethodCallNode.h @@ -1,4 +1,5 @@ #pragma once +#include "ast/declaration/VariableNode.h" #include "ast/expression/CallNode.h" #include "ast/expression/ListNode.h" #include "logging/LogMacros.h" diff --git a/source/ast/BlockNode.cc b/source/ast/BlockNode.cc index 826cdfbace5962e014b8c7b7a57c12442b82e03f..8f16957963453bae2917966d575d844ccd89afa0 100644 --- a/source/ast/BlockNode.cc +++ b/source/ast/BlockNode.cc @@ -13,6 +13,11 @@ BlockNode::~BlockNode() void BlockNode::add(Node* statement) { + if (statement == nullptr) + { + LOG_WARN("Attempted to add null statement to block"); + return; + } statements.push_back(statement); } diff --git a/source/ast/declaration/VariableNode.cc b/source/ast/declaration/VariableNode.cc index 69958e164d361185867b997f3bf5deebb813c676..dbff58ada1d576f03724d26aa978332d2292b8a9 100644 --- a/source/ast/declaration/VariableNode.cc +++ b/source/ast/declaration/VariableNode.cc @@ -32,6 +32,7 @@ Node* VariableNode::evaluate() const String VariableNode::to_s() const { + if (value == nullptr) { return "Variable: " + identifier; } return "Variable: " + identifier + " = " + value->to_s(); } @@ -74,4 +75,4 @@ void VariableNode::set_value(ExpressionNode* new_value) } else { throw RuntimeError(get_location(), "Cannot modify immutable variable '" + identifier + "'"); } } -} // namespace funk \ No newline at end of file +} // namespace funk diff --git a/source/ast/expression/ListNode.cc b/source/ast/expression/ListNode.cc index a09e44c35e355dc5cd0cfc5d88fd5fe8c8a3af3e..c6837df0df8a606b4ce496fa726963a7ca1b9105 100644 --- a/source/ast/expression/ListNode.cc +++ b/source/ast/expression/ListNode.cc @@ -33,7 +33,7 @@ NodeValue ListNode::get_value() const { ExpressionNode* result{dynamic_cast<ExpressionNode*>(evaluate())}; if (!result) { throw RuntimeError(location, "List did not evaluate to an expression"); } - return result->get_value(); + return NodeValue(result->to_s()); } size_t ListNode::length() const diff --git a/source/ast/expression/MethodCallNode.cc b/source/ast/expression/MethodCallNode.cc index 2a4afbca0072bd07e57f83887e123a3716de05a4..cefdb12989a377192dacfb3ec446509ae82d6a92 100644 --- a/source/ast/expression/MethodCallNode.cc +++ b/source/ast/expression/MethodCallNode.cc @@ -20,6 +20,12 @@ Node* MethodCallNode::evaluate() const Node* evaluated_object{object->evaluate()}; if (!evaluated_object) { throw RuntimeError(location, "Failed to evaluate object for method call"); } + if (auto var_node = dynamic_cast<VariableNode*>(evaluated_object)) + { + Node* var_value = var_node->get_value_node(); + if (var_value) { evaluated_object = var_value; } + } + if (auto list_node = dynamic_cast<ListNode*>(evaluated_object)) { if (identifier.get_lexeme() == "length") diff --git a/source/parser/Parser.cc b/source/parser/Parser.cc index d35ab7090a8b6ede22da105723616b7e7c80c9b6..2e098f2e1554ab708e6ef3f3f4f5be7797472da3 100644 --- a/source/parser/Parser.cc +++ b/source/parser/Parser.cc @@ -10,20 +10,22 @@ Node* Parser::parse(const Vector<String>& args) { LOG_DEBUG("Parse program"); - if (!args.empty()) - { - String arg_list{}; - for (const String& arg : args) { arg_list += arg + ", "; } - LOG_INFO("Arguments: " + arg_list.substr(0, arg_list.length() - 2)); - } - - // TODO: Handle arguments - BlockNode* block = new BlockNode(SourceLocation(filename, 0, 0)); + + LOG_DEBUG("Parsing arguments"); + + // Create a Vector of ExpressionNodes for the arguments + Vector<ExpressionNode*> list{}; + // Populate the Vector with LiteralNodes + for (const String& arg : args) { list.push_back(new LiteralNode(SourceLocation(filename, 0, 0), arg)); } + // Create a ListNode for the arguments + ExpressionNode* args_list{new ListNode(SourceLocation(filename, 0, 0), TokenType::TEXT, list)}; + // Create a DeclarationNode for the arguments + block->add(new DeclarationNode(SourceLocation(filename, 0, 0), true, TokenType::TEXT, "ARGS", args_list)); + // Parse the rest of the program while (!done()) { block->add(parse_statement()); } return block; } - Parser Parser::load(String filename) { Lexer lexer{read_file(filename), filename}; @@ -72,6 +74,13 @@ Node* Parser::parse_statement() { LOG_DEBUG("Parse statement"); + if (check(TokenType::COMMENT) || check(TokenType::BLOCK_COMMENT)) + { + LOG_INFO("Skipping comment"); + next(); + return nullptr; + } + Node* control{parse_control()}; if (control) { return control; }