From 058a18c612c6d4f33779058b07ba80b3854f2275 Mon Sep 17 00:00:00 2001 From: Justyna Ilczuk Date: Sun, 13 Jan 2013 17:36:38 +0100 Subject: [PATCH] More documentaaaaation. --- Sencha-lang/Context.cpp | 4 +- Sencha-lang/Context.h | 72 ++++++-- Sencha-lang/ContextManager.cpp | 8 +- Sencha-lang/ContextManager.h | 24 ++- Sencha-lang/Elements/Element.h | 4 + Sencha-lang/Elements/SenchaArray.h | 23 ++- Sencha-lang/Elements/SenchaFunction.h | 18 +- Sencha-lang/Elements/SenchaObject.cpp | 84 ++++++--- Sencha-lang/Elements/SenchaObject.h | 13 +- Sencha-lang/Lexer.h | 48 ++--- Sencha-lang/Object.cpp | 12 -- Sencha-lang/Object.h | 21 --- Sencha-lang/Parser.cpp | 10 +- Sencha-lang/Parser.h | 7 +- Sencha-lang/Tests/TestASTInspector.h | 12 +- Sencha-lang/Tests/TestLexer.cpp | 6 - Sencha-lang/Tests/TestLexer.h | 9 +- Sencha-lang/Tests/TestParser.h | 11 +- Sencha-lang/basic_native_functions.h | 121 +++++++++++++ Sencha-lang/customdoxygen.css | 4 +- Sencha-lang/header.html | 5 +- Sencha-lang/main.cpp | 241 +++++++------------------- Sencha-lang/sencha2 | 14 +- 23 files changed, 438 insertions(+), 333 deletions(-) delete mode 100644 Sencha-lang/Object.cpp delete mode 100644 Sencha-lang/Object.h create mode 100644 Sencha-lang/basic_native_functions.h diff --git a/Sencha-lang/Context.cpp b/Sencha-lang/Context.cpp index 172cc47..c6c007f 100644 --- a/Sencha-lang/Context.cpp +++ b/Sencha-lang/Context.cpp @@ -76,10 +76,10 @@ SenchaObject Context::get(std::string name) std::string Context::debug() { std::string debug_note = ""; - + debug_note += "Context: " + this->name + " contains:\n"; for( auto iter = this->object_store.begin(); iter != this->object_store.end(); iter++) { - debug_note += "Context: " + (*iter).second.repr() + ": " + (*iter).first + " " + "\n"; + debug_note += "name: " + (*iter).first + ", value: " + (*iter).second.repr() + "\n"; } return debug_note; diff --git a/Sencha-lang/Context.h b/Sencha-lang/Context.h index c432924..bd537b1 100644 --- a/Sencha-lang/Context.h +++ b/Sencha-lang/Context.h @@ -24,29 +24,77 @@ */ class Context { public: + /** + * Context has unique name, which is passed to it in constructor. + */ Context(std::string name); std::string name; + + /** + * Typedef to make further declarations easier to read. + */ typedef SenchaObject (*PointerToNativeFunction)(std::vector); + + /** + * Function have to be declared, which means here, registered before usage. + * You can register them with register_function functions. + */ void register_function(std::string name, PointerToNativeFunction f); void register_function(std::string name, SenchaFunction * f); - SenchaObject execute_native_function(std::string name, std::vector arguments); - SenchaObject get_updated_string(std::string name); - std::string debug() ; - void add(std::string name, SenchaObject object); - void set(std::string name, SenchaObject object); - SenchaObject get(std::string name); - bool contains_function(std::string name); - bool contains_sfunction(std::string name); - bool contains_nfunction(std::string name); + /** + * Map with function written in C++ stored like {"my_function" : &my_function} + */ std::map registered_functions; + /** + * Map with function written in Sencha stored like {"my_function" : &my_function} + */ std::map registered_sfunctions; + + /** + * contains_function("x") returns true if x can be found in registered native (c++) or sencha functions. + */ + bool contains_function(std::string name); + + /** + * contains_function("x") returns true if x can be found in registered sencha functions. + */ + bool contains_sfunction(std::string name); + + /** + * contains_function("x") returns true if x can be found in registered native (c++). + */ + bool contains_nfunction(std::string name); + + /** + * Executes function written in c++ + */ + SenchaObject execute_native_function(std::string name, std::vector arguments); + + /** + * get_updated_string(name) return string of given name with all updates done on its elements such as name[9] = "a"; + */ + SenchaObject get_updated_string(std::string name); + + /** + * debug() provides very useful info about context. What variables are stored, what are their values. + */ + std::string debug() ; + + /** + * add(name, value) adds value called name to object store. + */ + void add(std::string name, SenchaObject object); + + /** + * get(name) returns value from object store. If there isn't such a value. It returns SenchaObject(); + */ + SenchaObject get(std::string name); + + virtual ~Context(); private: unsigned int index; - - - std::map object_store; }; diff --git a/Sencha-lang/ContextManager.cpp b/Sencha-lang/ContextManager.cpp index 5575862..e042f79 100644 --- a/Sencha-lang/ContextManager.cpp +++ b/Sencha-lang/ContextManager.cpp @@ -18,7 +18,7 @@ ContextManager::~ContextManager() { Context * ContextManager::create_new_context() { - Context * context = new Context("Zdzislaw" + to_string(index)); + Context * context = new Context("abcd" + to_string(index)); index++; contexts[context->name] = context; stack.push(context); @@ -61,12 +61,6 @@ SenchaObject ContextManager::execute_function(std::string name, std::vector #include "Context.h" - +/** + * ContextManager manages contexts. + */ class ContextManager { public: ContextManager(); + /** + * execute_function(name, arguments) executes function giving her its own execution context. + */ + SenchaObject execute_function(std::string name, std::vector arguments); - std::stack stack; - std::map contexts; + //creation, destruction and basic access to contexts Context * create_new_context(); void destroy_context(std::string name); - Context * get_context(std::string name); Context * context(std::string name); + //access to contexts using stack Context * get_top(); - - SenchaObject execute_function(std::string name, std::vector arguments); void pop_context(); - unsigned int index; + virtual ~ContextManager(); +private: + /** + * Contexts are stored both in a stack (FILO) and in a map (indexed by names). + */ + std::stack stack; + std::map contexts; + unsigned int index; }; #endif /* CONTEXT_MANAGER_H_ */ diff --git a/Sencha-lang/Elements/Element.h b/Sencha-lang/Elements/Element.h index 3377c9a..8805a71 100644 --- a/Sencha-lang/Elements/Element.h +++ b/Sencha-lang/Elements/Element.h @@ -8,6 +8,10 @@ #ifndef ELEMENT_H_ #define ELEMENT_H_ +/** + * Basic element in sencha language design. Actually now it does nothing. + * It'd be changed in further versions. + */ class Element { public: diff --git a/Sencha-lang/Elements/SenchaArray.h b/Sencha-lang/Elements/SenchaArray.h index d100553..9632536 100644 --- a/Sencha-lang/Elements/SenchaArray.h +++ b/Sencha-lang/Elements/SenchaArray.h @@ -11,20 +11,35 @@ #include "Element.h" #include "../ContextManager.h" +/** + * SenchaArray is an abstraction of array element in a language. + * It provides access to its elements and some basic methods. + * It uses context_manager to evaluate its elements. SenchaArray is created on the go and stored nowhere. + */ class SenchaArray: public Element { public: + /** + * Basic, universal constructor. + */ SenchaArray(std::string name, ContextManager * context_manager); + + /** + * Special constructor, used to deal with strings + */ SenchaArray(std::string name, ContextManager * context_manager, std::string); - ContextManager * context_manager; - std::string name; + typedef int IndexNumber; IndexNumber add(SenchaObject value); void set(IndexNumber index, SenchaObject value); - IndexNumber max_index; SenchaObject get(IndexNumber index); - //lots of stuff virtual ~SenchaArray(); +private: + ContextManager * context_manager; + std::string name; + IndexNumber max_index; + + }; #endif /* SENCHAARRAY_H_ */ diff --git a/Sencha-lang/Elements/SenchaFunction.h b/Sencha-lang/Elements/SenchaFunction.h index 184f84c..e009df2 100644 --- a/Sencha-lang/Elements/SenchaFunction.h +++ b/Sencha-lang/Elements/SenchaFunction.h @@ -15,19 +15,23 @@ #include "../Utils/to_string.h" #include "../AST/ASTNode.h" - +/** + * SenchaFunction is a class which is an abstraction of function written in SenchaLang. + * It stores name of the function, its body, and provides () call operator. + */ class SenchaFunction : public Element { public: - std::string name; - std::vector names_of_arguments; - - ASTNode * body; - SenchaFunction(std::string name, std::vector names_of_arguments, ASTNode * body); SenchaObject operator()(); - + std::string name; + std::vector names_of_arguments; virtual ~SenchaFunction(); +private: + + + + ASTNode * body; }; #endif /* SENCHAFUNCTION_H_ */ diff --git a/Sencha-lang/Elements/SenchaObject.cpp b/Sencha-lang/Elements/SenchaObject.cpp index 5a22bb1..5031171 100644 --- a/Sencha-lang/Elements/SenchaObject.cpp +++ b/Sencha-lang/Elements/SenchaObject.cpp @@ -91,10 +91,6 @@ std::string SenchaObject::repr() representation = "type: null\n"; representation += "null"; break; - case symbol: - representation = "type: symbol\n"; - representation += this->text; - break; case invalid: representation = "type: invalid\n"; representation += "some crap"; @@ -122,9 +118,6 @@ std::string SenchaObject::str() case null: representation += "null"; break; - case symbol: - representation += this->text; - break; case invalid: representation += "some crap"; break; @@ -150,6 +143,15 @@ SenchaObject SenchaObject::operator+(const SenchaObject& right)const case float_number: result.set_value(this->number + right.number); break; + case boolean: + result.type = invalid; + break; + case invalid: + result.type = invalid; + break; + case null: + result.type = invalid; + break; } } else if(type == float_number && right.type == integer_number ) @@ -184,6 +186,15 @@ SenchaObject SenchaObject::operator-(const SenchaObject& right)const case float_number: result.set_value(this->number - right.number); break; + case boolean: + result.type = invalid; + break; + case invalid: + result.type = invalid; + break; + case null: + result.type = invalid; + break; } } else if(type == float_number && right.type == integer_number ) @@ -217,6 +228,15 @@ SenchaObject SenchaObject::operator*(const SenchaObject& right)const case float_number: result.set_value(this->number * right.number); break; + case boolean: + result.type = invalid; + break; + case invalid: + result.type = invalid; + break; + case null: + result.type = invalid; + break; } } else if(type == float_number && right.type == integer_number ) @@ -250,6 +270,15 @@ SenchaObject SenchaObject::operator/(const SenchaObject& right)const case float_number: result.set_value(this->number / right.number); break; + case boolean: + result.type = invalid; + break; + case invalid: + result.type = invalid; + break; + case null: + result.type = invalid; + break; } } else if(type == float_number && right.type == integer_number ) @@ -269,7 +298,7 @@ SenchaObject SenchaObject::operator/(const SenchaObject& right)const } SenchaObject SenchaObject::operator==(const SenchaObject& right)const - { + { SenchaObject result; bool value = false; result.type = boolean; @@ -301,15 +330,21 @@ SenchaObject SenchaObject::operator==(const SenchaObject& right)const value = true; } break; + case invalid: + result.type = invalid; + break; + case null: + result.type = invalid; + break; } } result.truthy = value; return result; - } + } SenchaObject SenchaObject::operator!=(const SenchaObject& right) const -{ + { SenchaObject result; result.type = boolean; @@ -319,7 +354,7 @@ SenchaObject SenchaObject::operator!=(const SenchaObject& right) const else result.truthy = true; return result; -} + } SenchaObject SenchaObject::operator>(const SenchaObject& right) const @@ -349,23 +384,32 @@ SenchaObject SenchaObject::operator>(const SenchaObject& right) const value = true; } break; + case invalid: + result.type = invalid; + break; + case boolean: + result.type = invalid; + break; + case null: + result.type = invalid; + break; } } else if(type == float_number && right.type == integer_number ) - { - value = (this->number > right.integer); - } - else if(type == integer_number && right.type == float_number) - { - value = (this->integer > right.number); - } + { + value = (this->number > right.integer); + } + else if(type == integer_number && right.type == float_number) + { + value = (this->integer > right.number); + } result.truthy = value; return result; } SenchaObject SenchaObject::operator>= (const SenchaObject& right) const -{ + { SenchaObject result; bool value = false; result.type = boolean; @@ -376,7 +420,7 @@ SenchaObject SenchaObject::operator>= (const SenchaObject& right) const } result.truthy = value; return result; -} + } SenchaObject SenchaObject::operator< (const SenchaObject& right) const { diff --git a/Sencha-lang/Elements/SenchaObject.h b/Sencha-lang/Elements/SenchaObject.h index 55d8501..6b062a9 100644 --- a/Sencha-lang/Elements/SenchaObject.h +++ b/Sencha-lang/Elements/SenchaObject.h @@ -12,21 +12,31 @@ #include "../Utils/to_string.h" #include "Element.h" + +/** + * SenchaObject stores values in SenchaLang. It handles operations on them, thanks to defined, overloaded operators. + * Also provides representation of values. + */ class SenchaObject : public Element { public: + /** + * Possible types of SenchaObject + */ typedef enum { string_literal, integer_number, float_number, null, - symbol, boolean, invalid } Type; Type type; + /** + * repr() returns representation of value as a string + */ virtual std::string repr(); virtual std::string str(); virtual bool is_true(); @@ -51,6 +61,7 @@ public: SenchaObject(std::string text) { set_value(text); } + //Operators used in expressions virtual SenchaObject operator< (const SenchaObject& right)const; virtual SenchaObject operator> (const SenchaObject& right)const; virtual SenchaObject operator<= (const SenchaObject& right)const; diff --git a/Sencha-lang/Lexer.h b/Sencha-lang/Lexer.h index cd3db82..d94f708 100644 --- a/Sencha-lang/Lexer.h +++ b/Sencha-lang/Lexer.h @@ -9,31 +9,39 @@ using namespace std; +/** + * Lexer is a class which gets some text, analyzes it and returns a vector of tokens. + */ class Lexer { - public: - Lexer(); - virtual ~Lexer(); - - void add_keyword(string word); - void add_punctuation_char(char c); - void add_operator(string oper); - string unescape_string(string text); - - vector parse_line(string line); - pair parse_token(string line); - type_of_token guess_type(string value); +public: + Lexer(); + virtual ~Lexer(); + /** + * parse_line(line) analyzes input and returns vector of tokens. + */ + vector parse_line(string line); + pair parse_token(string line); - bool is_keyword(string value); - bool is_punctuation(char c); - bool is_operator(string value ); + //helper function to evaluate type of token + bool is_keyword(string value); + bool is_punctuation(char c); + bool is_operator(string value ); - protected: - private: +private: + void add_keyword(string word); + void add_punctuation_char(char c); + void add_operator(string oper); + string unescape_string(string text); + + /** + * Tokens have type and value. Type is evaluated in function guess_type(value). + */ + type_of_token guess_type(string value); - vector keywords; - vector punctuation; - vector operators; + vector keywords; + vector punctuation; + vector operators; }; #endif // LEXER_H diff --git a/Sencha-lang/Object.cpp b/Sencha-lang/Object.cpp deleted file mode 100644 index 0badd08..0000000 --- a/Sencha-lang/Object.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "Object.h" - -Object::Object() -{ - number_value = 0; - //ctor -} - -Object::~Object() -{ - //dtor -} diff --git a/Sencha-lang/Object.h b/Sencha-lang/Object.h deleted file mode 100644 index 563cf7d..0000000 --- a/Sencha-lang/Object.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef OBJECT_H -#define OBJECT_H -#include -//I don't know how should it look like! -class Object -{ - public: - Object(); - virtual ~Object(); - //Representation of the object - std::string str(); - //Type - std::string type(); - //Possible values - double number_value; - std::string characters; - protected: - private: -}; - -#endif // OBJECT_H diff --git a/Sencha-lang/Parser.cpp b/Sencha-lang/Parser.cpp index e482c4f..954d6d4 100644 --- a/Sencha-lang/Parser.cpp +++ b/Sencha-lang/Parser.cpp @@ -118,15 +118,7 @@ bool Parser::is_type() else return false; } -bool Parser::is_function_name() -{ - if(context_manager->context("global")->contains_function(tok_value)) - { - read_next(); - return true; - } - else return false; -} + ASTStatement * Parser::statement() { diff --git a/Sencha-lang/Parser.h b/Sencha-lang/Parser.h index 261d3ef..ab44260 100644 --- a/Sencha-lang/Parser.h +++ b/Sencha-lang/Parser.h @@ -10,6 +10,9 @@ using namespace std; +/** + * Parser does parsing and produces AST. It provides root of AST which can be used to execute statements. + */ class Parser { public: @@ -47,9 +50,7 @@ class Parser protected: - private: - //Not used in current implementation, delete? - bool is_function_name(); + private: Token current_token; string tok_value; vector token_stream; diff --git a/Sencha-lang/Tests/TestASTInspector.h b/Sencha-lang/Tests/TestASTInspector.h index 4720cc1..61bb2bb 100644 --- a/Sencha-lang/Tests/TestASTInspector.h +++ b/Sencha-lang/Tests/TestASTInspector.h @@ -13,18 +13,22 @@ #include "../AST/BasicExpression.h" #include "../AST/ConstantExpression.h" - +/** + * TestASTInspector checks some basic features of ASTInspector. + */ class TestASTInspector: public TestSuite { public: TestASTInspector(); virtual ~TestASTInspector(); - - std::string test_inspecting_basic_expression(); - std::string test_inspecting_simple_AST(); virtual std::string all_tests(); private: + //tests + std::string test_inspecting_basic_expression(); + std::string test_inspecting_simple_AST(); + //helper functions BasicExpression * build_basic_expression(std::string oper, SenchaObject arg1, SenchaObject arg2); BasicExpression * build_simple_AST(std::string oper, BasicExpression * left, BasicExpression * right); + //instance of ASTInspector ASTInspector inspector; }; diff --git a/Sencha-lang/Tests/TestLexer.cpp b/Sencha-lang/Tests/TestLexer.cpp index 1000652..5491901 100644 --- a/Sencha-lang/Tests/TestLexer.cpp +++ b/Sencha-lang/Tests/TestLexer.cpp @@ -22,7 +22,6 @@ std::string TestLexer::all_tests() std::string test_report = ""; mu_run_test(test_searching_keyword_for_not_keyword); - mu_run_test(test_fake); mu_run_test(test_searching_keyword); mu_run_test(test_parsing_simple_token); mu_run_test(test_parsing_tricky_token); @@ -30,11 +29,6 @@ std::string TestLexer::all_tests() return test_report; } -std::string TestLexer::test_fake() -{ - mu_assert("1 == 1", 1 == 1); - return ""; -} std::string TestLexer::test_searching_keyword_for_not_keyword() { diff --git a/Sencha-lang/Tests/TestLexer.h b/Sencha-lang/Tests/TestLexer.h index 02876cb..eabe907 100644 --- a/Sencha-lang/Tests/TestLexer.h +++ b/Sencha-lang/Tests/TestLexer.h @@ -17,15 +17,14 @@ class TestLexer : public TestSuite { public: TestLexer(); virtual ~TestLexer(); + + virtual std::string all_tests(); +private: + Lexer lexer; std::string test_searching_keyword_for_not_keyword(); std::string test_searching_keyword(); std::string test_parsing_simple_token(); std::string test_parsing_tricky_token(); - - virtual std::string all_tests(); - std::string test_fake(); -private: - Lexer lexer; }; #endif /* TESTLEXER_H_ */ diff --git a/Sencha-lang/Tests/TestParser.h b/Sencha-lang/Tests/TestParser.h index a2a4843..ac4f119 100644 --- a/Sencha-lang/Tests/TestParser.h +++ b/Sencha-lang/Tests/TestParser.h @@ -16,24 +16,29 @@ #include - +/** + * TestParser is test suite for testing parser. + * It checks if parser works correctly. + * Features checked: defining and calling functions, array access, changing letters in strings and so on. + */ class TestParser: public TestSuite { public: TestParser(); virtual ~TestParser(); typedef std::pair InputOutputPair; typedef std::pair SInputOutputPair; + private: + //Actual tests std::string test_parsing_and_evaluating_logical_expressions(); std::string test_adding_new_function(); std::string test_calling_funtion(); - std::string prepare_some_function_declarations(); std::string test_writing_and_accessing_array_elements(); std::string test_changing_letters_in_string(); std::vector prepare_logical_input(); - + std::string prepare_some_function_declarations(); virtual std::string all_tests(); }; diff --git a/Sencha-lang/basic_native_functions.h b/Sencha-lang/basic_native_functions.h new file mode 100644 index 0000000..37ac5e3 --- /dev/null +++ b/Sencha-lang/basic_native_functions.h @@ -0,0 +1,121 @@ +#include +#include +#include +#include +#include "AST/AllTypesOfASTNodes.h" + +using namespace std; + +SenchaObject sleep(vector arguments) +{ + SenchaObject argument = arguments[0]->evaluate(); + if(argument.type == SenchaObject::integer_number && argument.integer >= 0) + { + cout << "valid argument for sleep: " << argument.integer << endl; + usleep(1000 * argument.integer); + return SenchaObject(); + } + else + { + cout << "invalid argument for sleep"; + argument.type = SenchaObject::invalid; + return argument; + } + +} + +SenchaObject print(vector arguments) +{ + for (auto argument: arguments) + { + auto value = argument->evaluate(); + + std::cout << value.str(); + + } + return SenchaObject(); +} + +SenchaObject println(vector arguments) +{ + for (auto argument: arguments) + { + auto value = argument->evaluate(); + + std::cout << value.str(); + + } + std::cout << std::endl; + return SenchaObject(); +} + +SenchaObject s_sin(vector arguments) +{ + SenchaObject result; + SenchaObject sin_argument = arguments[0]->evaluate(); + if(sin_argument.type == SenchaObject::integer_number) + { + result = SenchaObject(sin(sin_argument.integer)); + } + else if(sin_argument.type == SenchaObject::float_number) + { + result = SenchaObject(sin(sin_argument.number)); + } + else + { + result.type = SenchaObject::invalid; + } + + return result; +} + +SenchaObject s_cos(vector arguments) +{ + SenchaObject result; + SenchaObject cos_argument = arguments[0]->evaluate(); + if(cos_argument.type == SenchaObject::integer_number) + { + result = SenchaObject(cos(cos_argument.integer)); + } + else if(cos_argument.type == SenchaObject::float_number) + { + result = SenchaObject(cos(cos_argument.number)); + } + else + { + result.type = SenchaObject::invalid; + } + + return result; +} + +SenchaObject s_tan(vector arguments) +{ + SenchaObject result; + SenchaObject tan_argument = arguments[0]->evaluate(); + if(tan_argument.type == SenchaObject::integer_number) + { + result = SenchaObject(tan(tan_argument.integer)); + } + else if(tan_argument.type == SenchaObject::float_number) + { + result = SenchaObject(tan(tan_argument.number)); + } + else + { + result.type = SenchaObject::invalid; + } + + return result; +} + +SenchaObject len(vector arguments) +{ + SenchaObject result; + SenchaObject argument = arguments[0]->evaluate(); + if(argument.type == SenchaObject::string_literal) + { + result = SenchaObject(int(argument.text.size())); + } + return result; +} diff --git a/Sencha-lang/customdoxygen.css b/Sencha-lang/customdoxygen.css index 2642e8f..ca28439 100644 --- a/Sencha-lang/customdoxygen.css +++ b/Sencha-lang/customdoxygen.css @@ -187,8 +187,8 @@ div.line { word-wrap: break-word; /* IE 5.5+ */ text-indent: -53px; padding-left: 53px; - padding-bottom: 0px; - margin: 0px; + padding-bottom: 2px; + margin: 2px; -webkit-transition-property: background-color, box-shadow; -webkit-transition-duration: 0.5s; -moz-transition-property: background-color, box-shadow; diff --git a/Sencha-lang/header.html b/Sencha-lang/header.html index 78730af..888a70b 100644 --- a/Sencha-lang/header.html +++ b/Sencha-lang/header.html @@ -21,9 +21,10 @@ $extrastylesheet
- + - +
diff --git a/Sencha-lang/main.cpp b/Sencha-lang/main.cpp index 8d58e77..01fea68 100644 --- a/Sencha-lang/main.cpp +++ b/Sencha-lang/main.cpp @@ -9,148 +9,21 @@ #include "ContextManager.h" #include "ASTInspector.h" #include "Tests/tests.h" +#include "basic_native_functions.h" #include using namespace std; - -/*TODO - * Known bugs: - * - * >> print("I like bananas", dupa"); -I like bananasnull -Context: 0: dupa"); type: null -null - -dupa"); declaration? hello? It's probably temporary effect of searching for this name in variable tables - ->> - */ - - -SenchaObject sleep(vector arguments) +//Helper functions +void register_functions(ContextManager & context_manager) { - SenchaObject argument = arguments[0]->evaluate(); - if(argument.type == SenchaObject::integer_number && argument.integer >= 0) - { - cout << "valid argument for sleep: " << argument.integer << endl; - usleep(1000 * argument.integer); - return SenchaObject(); - } - else - { - cout << "invalid argument for sleep"; - argument.type = SenchaObject::invalid; - return argument; - } - -} -SenchaObject print(vector arguments) -{ - for (auto argument: arguments) - { - auto value = argument->evaluate(); - - std::cout << value.str(); - - } - return SenchaObject(); -} - -SenchaObject println(vector arguments) -{ - for (auto argument: arguments) - { - auto value = argument->evaluate(); - - std::cout << value.str(); - - } - std::cout << std::endl; - return SenchaObject(); -} - -SenchaObject s_sin(vector arguments) -{ - SenchaObject result; - SenchaObject sin_argument = arguments[0]->evaluate(); - if(sin_argument.type == SenchaObject::integer_number) - { - result = SenchaObject(sin(sin_argument.integer)); - } - else if(sin_argument.type == SenchaObject::float_number) - { - result = SenchaObject(sin(sin_argument.number)); - } - else - { - result.type = SenchaObject::invalid; - } - - return result; -} - -SenchaObject s_cos(vector arguments) -{ - SenchaObject result; - SenchaObject cos_argument = arguments[0]->evaluate(); - if(cos_argument.type == SenchaObject::integer_number) - { - result = SenchaObject(cos(cos_argument.integer)); - } - else if(cos_argument.type == SenchaObject::float_number) - { - result = SenchaObject(cos(cos_argument.number)); - } - else - { - result.type = SenchaObject::invalid; - } - - return result; -} - -SenchaObject s_tan(vector arguments) -{ - SenchaObject result; - SenchaObject tan_argument = arguments[0]->evaluate(); - if(tan_argument.type == SenchaObject::integer_number) - { - result = SenchaObject(tan(tan_argument.integer)); - } - else if(tan_argument.type == SenchaObject::float_number) - { - result = SenchaObject(tan(tan_argument.number)); - } - else - { - result.type = SenchaObject::invalid; - } - - return result; -} - -SenchaObject len(vector arguments) -{ - SenchaObject result; - SenchaObject argument = arguments[0]->evaluate(); - if(argument.type == SenchaObject::string_literal) - { - result = SenchaObject(int(argument.text.size())); - } - return result; -} - - -int how_depth_change(vector tokens) -{ - int change = 0; - for (unsigned int i = 0; i < tokens.size(); i++) - { - if(tokens[i].value == "{") change++; - else if(tokens[i].value == "}") change--; - } - return change; + context_manager.context("global")->register_function("print", print); + context_manager.context("global")->register_function("println", println); + context_manager.context("global")->register_function("sin", s_sin); + context_manager.context("global")->register_function("cos", s_cos); + context_manager.context("global")->register_function("tan", s_tan); + context_manager.context("global")->register_function("sleep", sleep); + context_manager.context("global")->register_function("len", len); } string compute_indentation(int depth_level) @@ -163,18 +36,24 @@ string compute_indentation(int depth_level) return indent; } +int how_depth_change(vector tokens) +{ + int change = 0; + for (unsigned int i = 0; i < tokens.size(); i++) + { + if(tokens[i].value == "{") change++; + else if(tokens[i].value == "}") change--; + } + return change; +} + void interactive() { + //Initialization Lexer lexer; ContextManager context_manager; - context_manager.context("global")->register_function("print", print); - context_manager.context("global")->register_function("println", println); - context_manager.context("global")->register_function("sin", s_sin); - context_manager.context("global")->register_function("cos", s_cos); - context_manager.context("global")->register_function("tan", s_tan); - context_manager.context("global")->register_function("sleep", sleep); - context_manager.context("global")->register_function("len", len); + register_functions(context_manager); Parser parser(&context_manager); ASTInspector inspector; @@ -183,6 +62,7 @@ void interactive() string input; int level_of_depth = 0; string indentation = ""; + //Main loop of interactive mode while(true) { cout << ">> " + indentation; @@ -195,6 +75,7 @@ void interactive() parser.add_tokens(tokens); + //It executes when statements and braces are closed if(level_of_depth == 0) { parser.interpret(); parser.program->execute_last(); @@ -206,55 +87,57 @@ void interactive() } } } + +void execute_script(std::string name ) +{ + Lexer lexer; + ContextManager context_manager; + register_functions(context_manager); + Parser parser(&context_manager); + + vector tokens; + string line; + ifstream input_file (name); + + if (input_file.is_open()) + { + while ( input_file.good() ) + { + getline (input_file,line); + tokens = lexer.parse_line(line); + parser.add_tokens(tokens); + } + input_file.close(); + } + parser.interpret(); + parser.program->execute(); +} + +/** + * Main function resolves in which mode user want to run program + * Modes are: + * Interactive - it is run when no arguments are provided + * Tests - "SenchaLang --test" + * Script execution - if path provided + */ int main(int argc, char *argv[]) { if(argc <= 1) { - cout << "Sencha-lang interpreter, version 0.12" << endl; + cout << "Sencha-lang interpreter, version 0.44" << endl; interactive(); } else { std::string argument1 = argv[1]; - if(argument1 == "--test") { - + if(argument1 == "--test") + { cout << "I'm running tests" << endl; run_tests(); } else { - auto name = argument1; - Lexer lexer; - ContextManager context_manager; - context_manager.context("global")->register_function("print", print); - context_manager.context("global")->register_function("println", println); - context_manager.context("global")->register_function("sin", s_sin); - context_manager.context("global")->register_function("cos", s_cos); - context_manager.context("global")->register_function("tan", s_tan); - context_manager.context("global")->register_function("sleep", sleep); - context_manager.context("global")->register_function("len", len); - - Parser parser(&context_manager); - - vector tokens; - string line; - ifstream input_file (name); - - if (input_file.is_open()) - { - while ( input_file.good() ) - { - getline (input_file,line); - tokens = lexer.parse_line(line); - parser.add_tokens(tokens); - } - input_file.close(); - } - ASTInspector inspector; - parser.interpret(); - inspector.visit(parser.tree.root); - parser.program->execute(); - //cout << inspector.get_report()<< endl; + execute_script(argument1); } } diff --git a/Sencha-lang/sencha2 b/Sencha-lang/sencha2 index a3c5e91..cc14c29 100644 --- a/Sencha-lang/sencha2 +++ b/Sencha-lang/sencha2 @@ -45,7 +45,7 @@ PROJECT_BRIEF = "Simple language interpreter, in developement" # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = /home/att/old/development/sencha-web/static/senchalogo2.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -835,7 +835,7 @@ USE_HTAGS = NO # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. -VERBATIM_HEADERS = YES +VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index @@ -892,13 +892,13 @@ HTML_FILE_EXTENSION = .html # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! -HTML_HEADER = +HTML_HEADER = header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. -HTML_FOOTER = +HTML_FOOTER = footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to @@ -907,7 +907,7 @@ HTML_FOOTER = # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. -HTML_STYLESHEET = +HTML_STYLESHEET = customdoxygen.css # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard @@ -963,7 +963,7 @@ HTML_TIMESTAMP = YES # documentation will contain sections that can be hidden and shown after the # page has loaded. -HTML_DYNAMIC_SECTIONS = NO +HTML_DYNAMIC_SECTIONS = YES # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user @@ -1214,7 +1214,7 @@ MATHJAX_EXTENSIONS = # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. -SEARCHENGINE = YES +SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client