// AUTOGENERATED COPYRIGHT HEADER START // Copyright (C) 2017-2025 Michael Fabian 'Xaymar' Dirks // AUTOGENERATED COPYRIGHT HEADER END #include #include #include "compiler.hpp" #include "error.hpp" #include "lexer.hpp" #include "parser.hpp" int main(int argc, char** argv) { try { std::setlocale(LC_ALL, "en_US.UTF-8"); std::cout << argv[1] << std::endl; std::list> nodes; std::shared_ptr lex2 = std::make_shared(argv[1]); for (blitz::token token = lex2->next(); (token.type != blitz::token::variant::ENDOFFILE); token = lex2->next()) { std::cout << token.to_string() << " "; if (token.type == blitz::token::variant::NEWLINE) { std::cout << std::endl; } if (token.type == blitz::token::variant::UNKNOWN) { std::cin.get(); } else if (blitz::ast::declare::can_parse(lex2)) { nodes.push_back(blitz::ast::declare::try_parse(lex2)); } else if (blitz::ast::value::can_parse(lex2)) { nodes.push_back(blitz::ast::value::try_parse(lex2)); } else if (blitz::ast::variable::can_parse(lex2)) { nodes.push_back(blitz::ast::variable::try_parse(lex2)); } } //std::cin.get(); return 0; } catch (blitz::error const& ex) { std::cout << std::endl << ex.file() << std::endl; std::cout << "Line " << ex.at().first << ", Char " << ex.at().second << ": " << ex.what() << std::endl; return 1; } catch (std::runtime_error const& ex) { std::cout << std::endl << ex.what() << std::endl; return 1; } } // BlitzBasic is a strange but powerful language in the right hands. While it has // somewhat unusual syntax and rules at times, it does not usually have ambigious // syntax and rules like C and C++ do. Overall, the quirks can be easily explained // and shouldn't cause odd problems. // // 1. Variables can be automatically defined if you did not define them before. // ``` // Local var1 ; Local Variable definition of var1 // Global var2 ; Global Variable definition of var2 // var1 = var3 ; Automatic definition of var3 as Local Variable // ``` // // 2. Names are not unique, and case-insensitive // ``` // Local myName ; Defines myName as Local // Local MyName ; Defines MyName as Local, should error because myName has already been defined. // Function myName() : End Function ; Defines myName as Function // Type myName ; Defines myName as Type // Field Bla // End Type // ``` // // 3. Function calls don't always need Parenthesis: // ``` // Local myName // Function myName() : End Function // If myName() Then : EndIf ; <- Calls myName // myName ; <- Calls myName, because there is no = after it. // ``` // // 4. Int(TypeVariable) returns the pointer to the TypeVariable: // ``` // Type myName // Field Bla // End Type // Local myName.myName = New myName // Print Int(myName) ; <- Prints the address of the object contained in myName. // ``` // // As this is a Basic language, there is no concept of undefined or uninitialized anything. Every behavior is "well" defined even if confusing.