146 lines
3.1 KiB
C++
146 lines
3.1 KiB
C++
#include <fstream>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <math.h>
|
|
#include "Token.h"
|
|
#include "Lexer.h"
|
|
#include "Parser.h"
|
|
#include "Tests/TestLexer.h"
|
|
#include "ContextManager.h"
|
|
#include "ASTInspector.h"
|
|
#include "Tests/tests.h"
|
|
#include "basic_native_functions.h"
|
|
#include <unistd.h>
|
|
|
|
using namespace std;
|
|
|
|
//Helper functions
|
|
void register_functions(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);
|
|
}
|
|
|
|
string compute_indentation(int depth_level)
|
|
{
|
|
string indent = "";
|
|
for(int i=0; i< depth_level; i++)
|
|
{
|
|
indent += " ";
|
|
}
|
|
return indent;
|
|
}
|
|
|
|
int how_depth_change(vector<Token> 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;
|
|
register_functions(context_manager);
|
|
|
|
Parser parser(&context_manager);
|
|
ASTInspector inspector;
|
|
vector<Token> tokens;
|
|
|
|
string input;
|
|
int level_of_depth = 0;
|
|
string indentation = "";
|
|
//Main loop of interactive mode
|
|
while(true)
|
|
{
|
|
cout << ">> " + indentation;
|
|
getline(cin, input);
|
|
if(input == "quit()") break;
|
|
tokens = lexer.parse_line(input);
|
|
|
|
level_of_depth += how_depth_change(tokens);
|
|
indentation = compute_indentation(level_of_depth);
|
|
|
|
parser.add_tokens(tokens);
|
|
|
|
//It executes when statements and braces are closed
|
|
if(level_of_depth == 0) {
|
|
parser.interpret();
|
|
parser.program->execute_last();
|
|
inspector.visit(parser.tree.root);
|
|
cout << context_manager.get_top()->debug() << endl;
|
|
//cout << parser.show_tokens();
|
|
cout << inspector.get_report();
|
|
inspector.forget_everything();
|
|
}
|
|
}
|
|
}
|
|
|
|
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.44" << endl;
|
|
interactive();
|
|
}
|
|
else
|
|
{
|
|
std::string argument1 = argv[1];
|
|
if(argument1 == "--test")
|
|
{
|
|
cout << "I'm running tests" << endl;
|
|
run_tests();
|
|
}
|
|
else {
|
|
execute_script(argument1);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|