📄 script.h
字号:
#include <string>
#include "filebuffer.h"
#include "cpptoken.h"
#include "except.h"
#include "scripttreedef.h"
__SCRIPT_NAMESPACE__
using std::string;
using std::vector;
class script_file
{
typedef CppToken<FileBuffer::iterator> token_t;
_default_handler _handler;
public:
script_file()
{
_df = new debug_files();
}
script_file(exception_handler_base * handler) : _handler(handler)
{
_df = new debug_files();
}
~script_file()
{
DEREF(_df);
}
bool read_file(const string &filename)
{
std::string lastfile = CurrentFile::Get();
CurrentFile::Set(filename.c_str());
FileBuffer fb;
bool succeed = false;
_df->add_filename(filename);
if(GetFileBuffer(filename, fb))
{
succeed = read_file(fb);
}
else
{
_handler(EFileNotExist(filename.c_str()));
}
CurrentFile::Set(lastfile.c_str());
return succeed;
}
bool read_file(FileBuffer &fb)
{
fb << "\n\n\n";
token_t token(fb.begin(), fb.end());
return read_file(token);
}
bool read_file(token_t token)
{
bool haserror = false;
while(true)
{
try
{
token_t tok(token);
++tok;
read_function(token);
LAUNCH(S_BATCH);
}
catch(EReachEndOfFile /*e*/)
{
break;
}
catch(CompileBaseException &e)
{
haserror = true;
_handler(e);
try
{
while(token != "function") ++token;
}
catch(EReachEndOfFile /*e*/)
{
break;
}
}
catch(EBatchExceptions &be)
{
be.for_each(_handler);
CLEAR(S_BATCH);
functions.remove(functions[functions.count()-1]);
try
{
while(token != "function") ++token;
}
catch(EReachEndOfFile /*e*/)
{
break;
}
}
}
return !haserror;
}
ref_list<script_function_tree> functions;
private:
bool is_identifier(const std::string & id)
{
return CppLex::IsLegal(id.begin(), id.end());
}
void read_function(token_t &token)
{
if(token != "function" && token != "object")
{
ERROR_TOK(UnexpectedToken, "non function declaration is not permitted.", token);
return;
}
token++;
script_function_tree * func = new script_function_tree(token.ToString());
token++;
id_list * param = read_parameter(token);
func->set_param_list(param);
statement * s = read_compound_statement(token);
func->set_body(s);
functions.add(func);
DEREF(param);
DEREF(s);
DEREF(func);
}
private:
id_list * read_parameter(token_t &token)
{
if(token != '(')
{
ERROR_TOK(UnexpectedToken, "list should be start with '('.", token);
return 0;
}
++token; // skip '('
id_list * il = read_id_list(token);
if(token != ')')
ERROR_TOK(UnexpectedToken, "parameter list should be terminated with ')'", token);
else
++token; // skip ')'
return il;
}
id_list * read_id_list(token_t &token)
{
id_list * il = new id_list();
if(is_identifier(token.ToString()))
{
il->add_id(token.ToString());
++token;
}
while(token == ',')
{
++token; // skip ','
if(is_identifier(token.ToString()))
il->add_id(token.ToString());
else
ERROR_TOK(IllegalIdentifier, "list item should be identifier", token);
++token; // skip id
}
return il;
}
compound_statement * read_compound_statement(token_t &token)
{
if(token != '{')
{
ERROR_TOK(UnexpectedToken, "compund statement should start with '{'.", token);
return 0;
}
++token; // skip '{'
compound_statement * cs = new compound_statement();
while(token != '}')
{
statement *s = read_statement(token);
cs->childs.add(s);
DEREF(s);
}
try
{
++token; // skip '}'
}
catch(EReachEndOfFile){}
return cs;
}
statement * read_statement(token_t &token)
{
if(token == '{')
return read_compound_statement(token);
if(token == "if")
return read_if_statement(token);
else if(token == "do")
return read_do_statement(token);
else if(token == "while")
return read_while_statement(token);
else if(token == "for")
return read_for_statement(token);
else if(token == "break" || token == "continue" || token == "return")
return read_jump_statement(token);
else
return read_expression_statement(token);
}
statement * read_if_statement(token_t &token)
{
++token; // skip 'if'
expression * cond = read_condition(token);
statement_if * si = new statement_if();
si->set_condition(cond);
DEREF(cond);
statement *s = read_statement(token);
si->set_truth_statement(s);
DEREF(s);
if(token == "else")
{
++token ; // skip 'else'
s = read_statement(token);
si->set_false_statement(s);
DEREF(s);
}
return si;
}
expression * read_condition(token_t &token)
{
if(token != '(')
{
ERROR_TOK(UnexpectedToken, "read_condition(): '(' is expected.", token);
return 0;
}
++token;
expression * exp = read_expression(token);
if(token != ')')
ERROR_TOK(UnexpectedToken, "read_condition(): ')' is expected.", token);
else
++token;
return exp;
}
statement * read_do_statement(token_t &token)
{
++token; // skip 'do'
statement_do * sd = new statement_do();
statement *s = read_statement(token);
sd->set_loop_statement(s);
DEREF(s);
if(token != "while")
{
ERROR_TOK(UnexpectedToken, "read_do_statment():'while' is expected.", token);
return sd;
}
++token; // skip 'while'
expression * cond = read_condition(token);
sd->set_loop_condition(cond);
DEREF(cond);
if(token != ';')
ERROR_TOK(UnexpectedToken, "read_do_statment(): ';' is expected.", token);
else ++token; // skip ';'
return sd;
}
statement * read_while_statement(token_t & token)
{
++token; // skip 'while'
statement_while * sw = new statement_while();
expression * cond = read_condition(token);
sw->set_loop_condition(cond);
DEREF(cond);
statement *s = read_statement(token);
sw->set_loop_statement(s);
DEREF(s);
return sw;
}
statement * read_for_statement(token_t &token)
{
++token; // skip 'for'
//if(token == "each") return read_for_each_statement(token);
statement_for *sf = new statement_for();
if(token != '(')
{
ERROR_TOK(UnexpectedToken, "read_for_statement(): '(' is expected.", token);
return sf;
}
++token; // skip ';'
statement *s = read_expression_statement(token);
sf->set_init_statement(s);
DEREF(s);
expression * exp = read_expression(token);
sf->set_loop_condition(exp);
DEREF(exp);
if(token != ';')
ERROR_TOK(UnexpectedToken, "read_for_statement(): ';' is expected.", token);
else
++token; // skip ';'
exp = read_expression(token);
sf->set_step_expression(exp);
DEREF(exp);
if(token != ')')
ERROR_TOK(UnexpectedToken, "read_for_statement(): ')' is expected.", token);
else
++token; // skip ')'
s = read_statement(token);
sf->set_loop_statement(s);
DEREF(s);
return sf;
}
/*statement * read_for_each_statement(token_t &token)
{
++token; // skip 'each'
statement_for_each *sf = new statement_for_each();
if(!is_identifier(token.ToString()))
THROW(IllegalIdentifier, "statement_for_each(): each variable should be identifier.", token);
sf->set_each_variable(token.ToString());
++token;
if(token != "in")
THROW(UnexpectedTerminator, "statement_for_each(): 'in' is expected.", token);
++token;
expression *exp = read_expression(token);
sf->set_aggaregation(exp);
DEREF(exp);
statement * s = read_statement(token);
sf->set_loop_statement(s);
DEREF(s);
return sf;
}*/
statement * read_jump_statement(token_t &token)
{
if(token == "continue")
{
++token;
if(token != ';')
ERROR_TOK(UnexpectedToken, "read_jump_statement(): ';' is expected.", token);
else
++token; // skip ';'
return new statement_continue();
}
else if(token == "break")
{
++token;
if(token != ';')
ERROR_TOK(UnexpectedToken, "read_jump_statement(): ';' is expected.", token);
else
++token; // skip ';'
return new statement_break();
}
else if(token == "return")
{
++token;
expression * exps = 0;
if(token != ';')
exps = read_list_expression(token);
if(token != ';')
ERROR_TOK(UnexpectedToken, "read_jump_statement(): ';' is expected.", token);
else
++token; // skip ';'
statement_return *sr = new statement_return();
sr->set_return_list(exps);
DEREF(exps);
return sr;
}
else
{
ERROR_TOK(UnknownScriptError, "read_jump_statement(): unknown error", token);
return 0;
}
}
statement * read_expression_statement(token_t &token)
{
expression *exp = 0;
if(token != ';')
exp = read_expression(token);
statement_exp * se = new statement_exp();
se->set_expression(exp);
DEREF(exp);
if(token != ';')
ERROR_TOK(UnexpectedToken, "read_expression_statement(): ';' is expected.", token);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -