diff options
author | Justyna Ilczuk <justyna.ilczuk@gmail.com> | 2013-01-13 17:36:38 +0100 |
---|---|---|
committer | Justyna Ilczuk <justyna.ilczuk@gmail.com> | 2013-01-13 17:36:38 +0100 |
commit | 058a18c612c6d4f33779058b07ba80b3854f2275 (patch) | |
tree | 6fcb75fb0ba30fc6104e83863aa93f3e15375c1e | |
parent | 837d4c4bce813919f6713f76c7c24404951751f6 (diff) | |
download | sencha-lang-master.tar.gz sencha-lang-master.tar.bz2 sencha-lang-master.tar.xz sencha-lang-master.zip |
-rw-r--r-- | Sencha-lang/Context.cpp | 4 | ||||
-rw-r--r-- | Sencha-lang/Context.h | 66 | ||||
-rw-r--r-- | Sencha-lang/ContextManager.cpp | 8 | ||||
-rw-r--r-- | Sencha-lang/ContextManager.h | 24 | ||||
-rw-r--r-- | Sencha-lang/Elements/Element.h | 4 | ||||
-rw-r--r-- | Sencha-lang/Elements/SenchaArray.h | 23 | ||||
-rw-r--r-- | Sencha-lang/Elements/SenchaFunction.h | 14 | ||||
-rw-r--r-- | Sencha-lang/Elements/SenchaObject.cpp | 84 | ||||
-rw-r--r-- | Sencha-lang/Elements/SenchaObject.h | 13 | ||||
-rw-r--r-- | Sencha-lang/Lexer.h | 48 | ||||
-rw-r--r-- | Sencha-lang/Object.cpp | 12 | ||||
-rw-r--r-- | Sencha-lang/Object.h | 21 | ||||
-rw-r--r-- | Sencha-lang/Parser.cpp | 10 | ||||
-rw-r--r-- | Sencha-lang/Parser.h | 7 | ||||
-rw-r--r-- | Sencha-lang/Tests/TestASTInspector.h | 12 | ||||
-rw-r--r-- | Sencha-lang/Tests/TestLexer.cpp | 6 | ||||
-rw-r--r-- | Sencha-lang/Tests/TestLexer.h | 9 | ||||
-rw-r--r-- | Sencha-lang/Tests/TestParser.h | 11 | ||||
-rw-r--r-- | Sencha-lang/basic_native_functions.h | 121 | ||||
-rw-r--r-- | Sencha-lang/customdoxygen.css | 4 | ||||
-rw-r--r-- | Sencha-lang/header.html | 5 | ||||
-rw-r--r-- | Sencha-lang/main.cpp | 229 | ||||
-rw-r--r-- | Sencha-lang/sencha2 | 14 |
23 files changed, 427 insertions, 322 deletions
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<ASTExpression *>); + + /** + * 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); + /** + * Map with function written in C++ stored like {"my_function" : &my_function} + */ + std::map<std::string, PointerToNativeFunction> registered_functions; + /** + * Map with function written in Sencha stored like {"my_function" : &my_function} + */ + std::map<std::string, SenchaFunction *> 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<ASTExpression *> 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); - void set(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); - bool contains_function(std::string name); - bool contains_sfunction(std::string name); - bool contains_nfunction(std::string name); - std::map<std::string, PointerToNativeFunction> registered_functions; - std::map<std::string, SenchaFunction *> registered_sfunctions; + + virtual ~Context(); private: unsigned int index; - - - std::map<std::string, SenchaObject> 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<ASTE } -Context * ContextManager::get_context(std::string name) -{ - return contexts[name]; - -} - Context * ContextManager::get_top() { return stack.top(); diff --git a/Sencha-lang/ContextManager.h b/Sencha-lang/ContextManager.h index 8b82342..be4ccc9 100644 --- a/Sencha-lang/ContextManager.h +++ b/Sencha-lang/ContextManager.h @@ -13,25 +13,35 @@ #include <stack> #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<ASTExpression *> arguments); - std::stack<Context *> stack; - std::map<std::string, Context *> 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<ASTExpression *> 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<Context *> stack; + std::map<std::string, Context *> 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: + SenchaFunction(std::string name, std::vector<std::string> names_of_arguments, ASTNode * body); + SenchaObject operator()(); std::string name; std::vector<std::string> names_of_arguments; + virtual ~SenchaFunction(); +private: - ASTNode * body; - SenchaFunction(std::string name, std::vector<std::string> names_of_arguments, ASTNode * body); - SenchaObject operator()(); - virtual ~SenchaFunction(); + 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<Token> parse_line(string line); - pair<string, Token> 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<Token> parse_line(string line);
+ pair<string, Token> parse_token(string line);
+
+ //helper function to evaluate type of token
+ bool is_keyword(string value);
+ bool is_punctuation(char c);
+ bool is_operator(string value ); - bool is_keyword(string value);
- bool is_punctuation(char c);
- bool is_operator(string value );
+private:
+ void add_keyword(string word);
+ void add_punctuation_char(char c);
+ void add_operator(string oper);
+ string unescape_string(string text);
- protected:
- private: + /**
+ * Tokens have type and value. Type is evaluated in function guess_type(value).
+ */
+ type_of_token guess_type(string value);
- vector<string> keywords; - vector<char> punctuation; - vector<string> operators;
+ vector<string> keywords; + vector<char> punctuation; + vector<string> 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 <string>
-//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> 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(); - 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; + 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(); }; #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 <vector> - +/** + * 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<std::string, bool> InputOutputPair; typedef std::pair<std::string, SenchaObject> 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<InputOutputPair> 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 <iostream> +#include <string> +#include <vector> +#include <math.h> +#include "AST/AllTypesOfASTNodes.h" + +using namespace std; + +SenchaObject sleep(vector<ASTExpression *> 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<ASTExpression *> arguments) +{ + for (auto argument: arguments) + { + auto value = argument->evaluate(); + + std::cout << value.str(); + + } + return SenchaObject(); +} + +SenchaObject println(vector<ASTExpression *> arguments) +{ + for (auto argument: arguments) + { + auto value = argument->evaluate(); + + std::cout << value.str(); + + } + std::cout << std::endl; + return SenchaObject(); +} + +SenchaObject s_sin(vector<ASTExpression *> 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<ASTExpression *> 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<ASTExpression *> 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<ASTExpression *> 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 <div id="titlearea"> <table cellspacing="0" cellpadding="0"> <tbody> - <tr style="height: 56px;"> + <tr style="height: 36px;"> <!--BEGIN PROJECT_LOGO--> - <td id="projectlogo"><img alt="Logo" src="$relpath$$projectlogo"/></td> + <td id="projectlogo"><img alt="Logo" height="130" + width="80" src="$relpath$$projectlogo"/></td> <!--END PROJECT_LOGO--> <!--BEGIN PROJECT_NAME--> <td style="padding-left: 0.5em;"> 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,139 +9,33 @@ #include "ContextManager.h" #include "ASTInspector.h" #include "Tests/tests.h" +#include "basic_native_functions.h" #include <unistd.h> 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<ASTExpression *> 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<ASTExpression *> arguments) -{ - for (auto argument: arguments) - { - auto value = argument->evaluate(); - - std::cout << value.str(); - - } - return SenchaObject(); -} - -SenchaObject println(vector<ASTExpression *> arguments) -{ - for (auto argument: arguments) - { - auto value = argument->evaluate(); - - std::cout << value.str(); - - } - std::cout << std::endl; - return SenchaObject(); -} - -SenchaObject s_sin(vector<ASTExpression *> arguments) +//Helper functions +void register_functions(ContextManager & context_manager) { - 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<ASTExpression *> 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<ASTExpression *> 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; + 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); } -SenchaObject len(vector<ASTExpression *> arguments) +string compute_indentation(int depth_level) { - SenchaObject result; - SenchaObject argument = arguments[0]->evaluate(); - if(argument.type == SenchaObject::string_literal) + string indent = ""; + for(int i=0; i< depth_level; i++) { - result = SenchaObject(int(argument.text.size())); + indent += " "; } - return result; + return indent; } - int how_depth_change(vector<Token> tokens) { int change = 0; @@ -153,28 +47,13 @@ int how_depth_change(vector<Token> tokens) return change; } -string compute_indentation(int depth_level) -{ - string indent = ""; - for(int i=0; i< depth_level; i++) - { - indent += " "; - } - return indent; -} - 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<Token> 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<Token> 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 |