🎨 improve format of code
This commit is contained in:
parent
c705b75513
commit
d121dcd630
8
main.cpp
8
main.cpp
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include <unordered_map>
|
||||
|
||||
using ch_clk=std::chrono::high_resolution_clock;
|
||||
|
||||
const u32 VM_TOKEN =0x01;
|
||||
const u32 VM_AST =0x02;
|
||||
const u32 VM_CODE =0x04;
|
||||
|
@ -114,10 +116,10 @@ void execute(const string& file,const std::vector<string>& argv,const u32 cmd)
|
|||
debugger(err).run(gen,ld,argv);
|
||||
else if(cmd&VM_TIME)
|
||||
{
|
||||
auto start=std::chrono::high_resolution_clock::now();
|
||||
auto start=ch_clk::now();
|
||||
ctx.run(gen,ld,argv,cmd&VM_DETAIL);
|
||||
auto end=std::chrono::high_resolution_clock::now();
|
||||
std::clog<<"process exited after "<<(end-start).count()*1.0/std::chrono::high_resolution_clock::duration::period::den<<"s.\n";
|
||||
auto end=ch_clk::now();
|
||||
std::clog<<"process exited after "<<(end-start).count()*1.0/ch_clk::duration::period::den<<"s.\n";
|
||||
}
|
||||
else if(cmd&VM_EXEC)
|
||||
ctx.run(gen,ld,argv,cmd&VM_DETAIL);
|
||||
|
|
8
nasal.h
8
nasal.h
|
@ -1,6 +1,8 @@
|
|||
#ifndef __NASAL_H__
|
||||
#define __NASAL_H__
|
||||
#pragma once
|
||||
|
||||
#ifndef __nasver
|
||||
#define __nasver "10.1"
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
@ -151,5 +153,3 @@ string rawstr(const string& str,const usize maxlen=0)
|
|||
}
|
||||
|
||||
#include "nasal_gc.h" // declarations of var and nasal_gc
|
||||
|
||||
#endif
|
||||
|
|
143
nasal_ast.h
143
nasal_ast.h
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_AST_H__
|
||||
#define __NASAL_AST_H__
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
@ -53,12 +52,12 @@ enum ast_node:u32
|
|||
ast_foreach, // foreach keyword
|
||||
ast_while, // while
|
||||
ast_iter, // iterator, used in forindex/foreach
|
||||
ast_conditional, // mark a sub-tree of conditional expression
|
||||
ast_cond, // mark a sub-tree of conditional expression
|
||||
ast_if, // if keyword
|
||||
ast_elsif, // elsif keyword
|
||||
ast_else, // else keyword
|
||||
ast_multi_id, // multi identifiers sub-tree
|
||||
ast_multi_scalar,// multi value sub-tree
|
||||
ast_tuple, // tuple, only used in multiple assignment
|
||||
ast_def, // definition
|
||||
ast_multi_assign,// multi assignment sub-tree
|
||||
ast_continue, // continue keyword, only used in loop
|
||||
|
@ -107,20 +106,20 @@ const char* ast_name[]=
|
|||
"*",
|
||||
"/",
|
||||
"~",
|
||||
"unary-",
|
||||
"unary!",
|
||||
"neg",
|
||||
"!",
|
||||
"trino",
|
||||
"for",
|
||||
"forindex",
|
||||
"foreach",
|
||||
"while",
|
||||
"iter",
|
||||
"conditional",
|
||||
"cond",
|
||||
"if",
|
||||
"elsif",
|
||||
"else",
|
||||
"multi-id",
|
||||
"multi-scalar",
|
||||
"tuple",
|
||||
"def",
|
||||
"multi-assign",
|
||||
"continue",
|
||||
|
@ -131,15 +130,15 @@ const char* ast_name[]=
|
|||
class ast
|
||||
{
|
||||
private:
|
||||
u32 node_line;
|
||||
u32 node_col;
|
||||
u32 node_type;
|
||||
f64 node_num;
|
||||
string node_str;
|
||||
std::vector<ast> node_child;
|
||||
u32 nd_line;
|
||||
u32 nd_col;
|
||||
u32 nd_type;
|
||||
f64 nd_num;
|
||||
string nd_str;
|
||||
std::vector<ast> nd_child;
|
||||
public:
|
||||
ast(const u32 l,const u32 c,const u32 t):
|
||||
node_line(l),node_col(c),node_type(t),node_num(0){}
|
||||
nd_line(l),nd_col(c),nd_type(t),nd_num(0){}
|
||||
ast(const ast&);
|
||||
ast(ast&&);
|
||||
void print_tree();
|
||||
|
@ -148,74 +147,74 @@ public:
|
|||
|
||||
ast& operator=(const ast&);
|
||||
ast& operator=(ast&&);
|
||||
ast& operator[](usize n){return node_child[n];}
|
||||
const ast& operator[](usize n) const {return node_child[n];}
|
||||
usize size() const {return node_child.size();}
|
||||
ast& operator[](usize n){return nd_child[n];}
|
||||
const ast& operator[](usize n) const {return nd_child[n];}
|
||||
usize size() const {return nd_child.size();}
|
||||
|
||||
void add(ast&& node){node_child.push_back(std::move(node));}
|
||||
void add(const ast& node){node_child.push_back(node);}
|
||||
void set_line(const u32 l){node_line=l;}
|
||||
void set_type(const u32 t){node_type=t;}
|
||||
void set_str(const string& s){node_str=s;}
|
||||
void set_num(const f64 n){node_num=n;}
|
||||
void add(ast&& node){nd_child.push_back(std::move(node));}
|
||||
void add(const ast& node){nd_child.push_back(node);}
|
||||
void set_line(const u32 l){nd_line=l;}
|
||||
void set_type(const u32 t){nd_type=t;}
|
||||
void set_str(const string& s){nd_str=s;}
|
||||
void set_num(const f64 n){nd_num=n;}
|
||||
|
||||
inline u32 line() const {return node_line;}
|
||||
inline u32 col() const {return node_col;}
|
||||
inline u32 type() const {return node_type;}
|
||||
inline f64 num() const {return node_num;}
|
||||
inline const string& str() const {return node_str;}
|
||||
inline const std::vector<ast>& child() const {return node_child;}
|
||||
inline std::vector<ast>& child(){return node_child;}
|
||||
inline u32 line() const {return nd_line;}
|
||||
inline u32 col() const {return nd_col;}
|
||||
inline u32 type() const {return nd_type;}
|
||||
inline f64 num() const {return nd_num;}
|
||||
inline const string& str() const {return nd_str;}
|
||||
inline const std::vector<ast>& child() const {return nd_child;}
|
||||
inline std::vector<ast>& child(){return nd_child;}
|
||||
};
|
||||
|
||||
ast::ast(const ast& tmp):
|
||||
node_str(tmp.node_str),node_child(tmp.node_child)
|
||||
nd_str(tmp.nd_str),nd_child(tmp.nd_child)
|
||||
{
|
||||
node_line=tmp.node_line;
|
||||
node_col=tmp.node_col;
|
||||
node_type=tmp.node_type;
|
||||
node_num =tmp.node_num;
|
||||
nd_line=tmp.nd_line;
|
||||
nd_col=tmp.nd_col;
|
||||
nd_type=tmp.nd_type;
|
||||
nd_num =tmp.nd_num;
|
||||
}
|
||||
|
||||
ast::ast(ast&& tmp)
|
||||
{
|
||||
node_line=tmp.node_line;
|
||||
node_col=tmp.node_col;
|
||||
node_type=tmp.node_type;
|
||||
node_num =tmp.node_num;
|
||||
node_str.swap(tmp.node_str);
|
||||
node_child.swap(tmp.node_child);
|
||||
nd_line=tmp.nd_line;
|
||||
nd_col=tmp.nd_col;
|
||||
nd_type=tmp.nd_type;
|
||||
nd_num =tmp.nd_num;
|
||||
nd_str.swap(tmp.nd_str);
|
||||
nd_child.swap(tmp.nd_child);
|
||||
}
|
||||
|
||||
ast& ast::operator=(const ast& tmp)
|
||||
{
|
||||
node_line=tmp.node_line;
|
||||
node_col=tmp.node_col;
|
||||
node_type=tmp.node_type;
|
||||
node_num=tmp.node_num;
|
||||
node_str=tmp.node_str;
|
||||
node_child=tmp.node_child;
|
||||
nd_line=tmp.nd_line;
|
||||
nd_col=tmp.nd_col;
|
||||
nd_type=tmp.nd_type;
|
||||
nd_num=tmp.nd_num;
|
||||
nd_str=tmp.nd_str;
|
||||
nd_child=tmp.nd_child;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ast& ast::operator=(ast&& tmp)
|
||||
{
|
||||
node_line=tmp.node_line;
|
||||
node_col=tmp.node_col;
|
||||
node_type=tmp.node_type;
|
||||
node_num=tmp.node_num;
|
||||
node_str.swap(tmp.node_str);
|
||||
node_child.swap(tmp.node_child);
|
||||
nd_line=tmp.nd_line;
|
||||
nd_col=tmp.nd_col;
|
||||
nd_type=tmp.nd_type;
|
||||
nd_num=tmp.nd_num;
|
||||
nd_str.swap(tmp.nd_str);
|
||||
nd_child.swap(tmp.nd_child);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ast::clear()
|
||||
{
|
||||
node_line=node_col=0;
|
||||
node_num=0;
|
||||
node_str.clear();
|
||||
node_type=ast_null;
|
||||
node_child.clear();
|
||||
nd_line=nd_col=0;
|
||||
nd_num=0;
|
||||
nd_str.clear();
|
||||
nd_type=ast_null;
|
||||
nd_child.clear();
|
||||
}
|
||||
|
||||
void ast::print_tree()
|
||||
|
@ -228,15 +227,13 @@ void ast::print(u32 depth,bool last,std::vector<string>& indent)
|
|||
{
|
||||
for(auto& i:indent)
|
||||
std::cout<<i;
|
||||
std::cout<<ast_name[node_type];
|
||||
if(node_type==ast_str ||
|
||||
node_type==ast_id ||
|
||||
node_type==ast_default ||
|
||||
node_type==ast_dynamic ||
|
||||
node_type==ast_callh)
|
||||
std::cout<<":"<<rawstr(node_str);
|
||||
else if(node_type==ast_num || node_type==ast_file)
|
||||
std::cout<<":"<<node_num;
|
||||
std::cout<<ast_name[nd_type];
|
||||
if(nd_type==ast_str || nd_type==ast_id ||
|
||||
nd_type==ast_default || nd_type==ast_dynamic ||
|
||||
nd_type==ast_callh)
|
||||
std::cout<<":"<<rawstr(nd_str);
|
||||
else if(nd_type==ast_num || nd_type==ast_file)
|
||||
std::cout<<":"<<nd_num;
|
||||
std::cout<<"\n";
|
||||
if(last && depth)
|
||||
indent.back()=" ";
|
||||
|
@ -246,16 +243,14 @@ void ast::print(u32 depth,bool last,std::vector<string>& indent)
|
|||
#else
|
||||
indent.back()="│ ";
|
||||
#endif
|
||||
for(u32 i=0;i<node_child.size();++i)
|
||||
for(u32 i=0;i<nd_child.size();++i)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
indent.push_back(i==node_child.size()-1?"+-":"|-");
|
||||
indent.push_back(i==nd_child.size()-1?"+-":"|-");
|
||||
#else
|
||||
indent.push_back(i==node_child.size()-1?"└─":"├─");
|
||||
indent.push_back(i==nd_child.size()-1?"└─":"├─");
|
||||
#endif
|
||||
node_child[i].print(depth+1,i==node_child.size()-1,indent);
|
||||
nd_child[i].print(depth+1,i==nd_child.size()-1,indent);
|
||||
indent.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_BUILTIN_H__
|
||||
#define __NASAL_BUILTIN_H__
|
||||
#pragma once
|
||||
|
||||
#include "nasal_gc.h"
|
||||
|
||||
|
@ -1231,4 +1230,3 @@ struct
|
|||
{"__logtime", builtin_logtime },
|
||||
{nullptr, nullptr }
|
||||
};
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_CODEGEN_H__
|
||||
#define __NASAL_CODEGEN_H__
|
||||
#pragma once
|
||||
|
||||
#include "nasal_err.h"
|
||||
#include <iomanip>
|
||||
|
@ -248,7 +247,7 @@ private:
|
|||
void single_def(const ast&);
|
||||
void def_gen(const ast&);
|
||||
void multi_assign_gen(const ast&);
|
||||
void conditional_gen(const ast&);
|
||||
void cond_gen(const ast&);
|
||||
void loop_gen(const ast&);
|
||||
void load_continue_break(i32,i32);
|
||||
void while_gen(const ast&);
|
||||
|
@ -649,7 +648,7 @@ void codegen::multi_def(const ast& node)
|
|||
{
|
||||
auto& ids=node[0].child();
|
||||
usize size=ids.size();
|
||||
if(node[1].type()==ast_multi_scalar) // (var a,b,c)=(c,b,a);
|
||||
if(node[1].type()==ast_tuple) // (var a,b,c)=(c,b,a);
|
||||
{
|
||||
auto& vals=node[1].child();
|
||||
for(usize i=0;i<size;++i)
|
||||
|
@ -684,7 +683,7 @@ void codegen::def_gen(const ast& node)
|
|||
void codegen::multi_assign_gen(const ast& node)
|
||||
{
|
||||
i32 size=node[0].size();
|
||||
if(node[1].type()==ast_multi_scalar)
|
||||
if(node[1].type()==ast_tuple)
|
||||
{
|
||||
for(i32 i=size-1;i>=0;--i)
|
||||
calc_gen(node[1][i]);
|
||||
|
@ -725,7 +724,7 @@ void codegen::multi_assign_gen(const ast& node)
|
|||
}
|
||||
}
|
||||
|
||||
void codegen::conditional_gen(const ast& node)
|
||||
void codegen::cond_gen(const ast& node)
|
||||
{
|
||||
std::vector<usize> jmp_label;
|
||||
for(auto& tmp:node.child())
|
||||
|
@ -1146,7 +1145,7 @@ void codegen::block_gen(const ast& node)
|
|||
case ast_file:fileindex=tmp.num();break; // special node type in main block
|
||||
case ast_def:def_gen(tmp);break;
|
||||
case ast_multi_assign:multi_assign_gen(tmp);break;
|
||||
case ast_conditional:conditional_gen(tmp);break;
|
||||
case ast_cond:cond_gen(tmp);break;
|
||||
case ast_continue:
|
||||
continue_ptr.front().push_back(code.size());
|
||||
gen(op_jmp,0,tmp.line());
|
||||
|
@ -1288,5 +1287,3 @@ void codegen::print()
|
|||
for(u32 i=0;i<code.size();++i)
|
||||
singleop(i);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_DBG_H__
|
||||
#define __NASAL_DBG_H__
|
||||
#pragma once
|
||||
|
||||
#include "nasal_err.h"
|
||||
#include "nasal_vm.h"
|
||||
|
@ -126,7 +125,7 @@ void debugger::stepinfo()
|
|||
for(u32 i=begin;i<end && bytecode[i].op!=op_exit;++i)
|
||||
std::cout
|
||||
<<(i==pc?back_white:reset)<<(i==pc?"--> ":" ")
|
||||
<<codestream(bytecode[i],i,num_table,str_table,files)
|
||||
<<codestream(bytecode[i],i,cnum,cstr,files)
|
||||
<<reset<<"\n";
|
||||
stackinfo(10);
|
||||
}
|
||||
|
@ -399,5 +398,3 @@ mcallh: dbg(o_mcallh,op_mcallh);
|
|||
ret: dbg(o_ret ,op_ret );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_ERR_H__
|
||||
#define __NASAL_ERR_H__
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
@ -159,5 +158,3 @@ public:
|
|||
}
|
||||
void chkerr(){if(cnt)std::exit(1);}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_GC_H__
|
||||
#define __NASAL_GC_H__
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
@ -725,5 +724,3 @@ var nas_err(const string& err_f,const string& info)
|
|||
|
||||
typedef var (*mod)(var*,usize,gc*); // module function type
|
||||
typedef mod (*getptr)(const char*); // module function "get" type
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_IMPORT_H__
|
||||
#define __NASAL_IMPORT_H__
|
||||
#pragma once
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
|
@ -224,5 +223,3 @@ void linker::link(parse& parse,const string& self,bool spath=false)
|
|||
parse.tree()=load(parse.tree(),0);
|
||||
err.chkerr();
|
||||
}
|
||||
|
||||
#endif
|
133
nasal_lexer.h
133
nasal_lexer.h
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_LEXER_H__
|
||||
#define __NASAL_LEXER_H__
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
|
@ -8,18 +7,6 @@
|
|||
#define S_ISREG(m) (((m)&0xF000)==0x8000)
|
||||
#endif
|
||||
|
||||
#define ID(c) ((c=='_')||('a'<=c && c<='z')||('A'<=c&&c<='Z')||(c<0))
|
||||
#define HEX(c) (('0'<=c&&c<='9')||('a'<=c&&c<='f')||('A'<=c && c<='F'))
|
||||
#define OCT(c) ('0'<=c&&c<='7')
|
||||
#define DIGIT(c) ('0'<=c&&c<='9')
|
||||
#define STR(c) (c=='\''||c=='\"'||c=='`')
|
||||
// single operators have only one character
|
||||
#define SINGLE_OPERATOR(c) (c=='('||c==')'||c=='['||c==']'||c=='{'||c=='}'||c==','||c==';'||c=='|'||c==':'||\
|
||||
c=='?'||c=='`'||c=='&'||c=='@'||c=='%'||c=='$'||c=='^'||c=='\\')
|
||||
// calculation operators may have two chars, for example: += -= *= /= ~= != == >= <=
|
||||
#define CALC_OPERATOR(c) (c=='='||c=='+'||c=='-'||c=='*'||c=='!'||c=='/'||c=='<'||c=='>'||c=='~')
|
||||
#define NOTE(c) (c=='#')
|
||||
|
||||
enum tok:u32{
|
||||
tok_null=0, // null token (default token type)
|
||||
tok_num, // number literal
|
||||
|
@ -38,15 +25,39 @@ enum tok:u32{
|
|||
tok_elsif, // condition expression keyword elsif
|
||||
tok_else, // condition expression keyword else
|
||||
tok_nil, // nil literal
|
||||
tok_lcurve,tok_rcurve,
|
||||
tok_lbracket,tok_rbracket,
|
||||
tok_lbrace,tok_rbrace,
|
||||
tok_semi,tok_and,tok_or,tok_comma,tok_dot,tok_ellipsis,tok_quesmark,
|
||||
tok_colon,tok_add,tok_sub,tok_mult,tok_div,tok_link,tok_not,
|
||||
tok_eq,
|
||||
tok_addeq,tok_subeq,tok_multeq,tok_diveq,tok_lnkeq,
|
||||
tok_cmpeq,tok_neq,tok_less,tok_leq,tok_grt,tok_geq,
|
||||
tok_eof // end of token list
|
||||
tok_lcurve, // (
|
||||
tok_rcurve, // )
|
||||
tok_lbracket,// [
|
||||
tok_rbracket,// ]
|
||||
tok_lbrace, // {
|
||||
tok_rbrace, // }
|
||||
tok_semi, // ;
|
||||
tok_and, // operator and
|
||||
tok_or, // operator or
|
||||
tok_comma, // ,
|
||||
tok_dot, // .
|
||||
tok_ellipsis,// ...
|
||||
tok_quesmark,// ?
|
||||
tok_colon, // :
|
||||
tok_add, // operator +
|
||||
tok_sub, // operator -
|
||||
tok_mult, // operator *
|
||||
tok_div, // operator /
|
||||
tok_link, // operator ~
|
||||
tok_not, // operator !
|
||||
tok_eq, // operator =
|
||||
tok_addeq, // operator +=
|
||||
tok_subeq, // operator -=
|
||||
tok_multeq, // operator *=
|
||||
tok_diveq, // operator /=
|
||||
tok_lnkeq, // operator ~=
|
||||
tok_cmpeq, // operator ==
|
||||
tok_neq, // operator !=
|
||||
tok_less, // operator <
|
||||
tok_leq, // operator <=
|
||||
tok_grt, // operator >
|
||||
tok_geq, // operator >=
|
||||
tok_eof // <eof> end of token list
|
||||
};
|
||||
|
||||
struct{
|
||||
|
@ -126,6 +137,13 @@ private:
|
|||
std::vector<token> tokens;
|
||||
|
||||
u32 get_type(const string&);
|
||||
bool is_id(char);
|
||||
bool is_hex(char);
|
||||
bool is_oct(char);
|
||||
bool is_dec(char);
|
||||
bool is_str(char);
|
||||
bool is_single_opr(char);
|
||||
bool is_calc_opr(char);
|
||||
void die(const string& info){err.err("lexer",line,column,info);}
|
||||
void open(const string&);
|
||||
string utf8_gen();
|
||||
|
@ -142,6 +160,47 @@ public:
|
|||
const std::vector<token>& result() const {return tokens;}
|
||||
};
|
||||
|
||||
bool lexer::is_id(char c)
|
||||
{
|
||||
return (c=='_')||('a'<=c && c<='z')||('A'<=c&&c<='Z')||(c<0);
|
||||
}
|
||||
|
||||
bool lexer::is_hex(char c)
|
||||
{
|
||||
return ('0'<=c&&c<='9')||('a'<=c&&c<='f')||('A'<=c && c<='F');
|
||||
}
|
||||
|
||||
bool lexer::is_oct(char c)
|
||||
{
|
||||
return '0'<=c&&c<='7';
|
||||
}
|
||||
|
||||
bool lexer::is_dec(char c)
|
||||
{
|
||||
return '0'<=c&&c<='9';
|
||||
}
|
||||
|
||||
bool lexer::is_str(char c)
|
||||
{
|
||||
return c=='\''||c=='\"'||c=='`';
|
||||
}
|
||||
|
||||
bool lexer::is_single_opr(char c)
|
||||
{
|
||||
return (
|
||||
c=='('||c==')'||c=='['||c==']'||
|
||||
c=='{'||c=='}'||c==','||c==';'||
|
||||
c=='|'||c==':'||c=='?'||c=='`'||
|
||||
c=='&'||c=='@'||c=='%'||c=='$'||
|
||||
c=='^'||c=='\\'
|
||||
);
|
||||
}
|
||||
|
||||
bool lexer::is_calc_opr(char c)
|
||||
{
|
||||
return c=='='||c=='+'||c=='-'||c=='*'||c=='!'||c=='/'||c=='<'||c=='>'||c=='~';
|
||||
}
|
||||
|
||||
void lexer::open(const string& file)
|
||||
{
|
||||
struct stat buffer;
|
||||
|
@ -205,7 +264,7 @@ string lexer::utf8_gen()
|
|||
string lexer::id_gen()
|
||||
{
|
||||
string str="";
|
||||
while(ptr<res.size() && (ID(res[ptr])||DIGIT(res[ptr])))
|
||||
while(ptr<res.size() && (is_id(res[ptr])||is_dec(res[ptr])))
|
||||
{
|
||||
if(res[ptr]<0) // utf-8
|
||||
str+=utf8_gen();
|
||||
|
@ -225,7 +284,7 @@ string lexer::num_gen()
|
|||
{
|
||||
string str="0x";
|
||||
ptr+=2;
|
||||
while(ptr<res.size() && HEX(res[ptr]))
|
||||
while(ptr<res.size() && is_hex(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
column+=str.length();
|
||||
if(str.length()<3)// "0x"
|
||||
|
@ -237,7 +296,7 @@ string lexer::num_gen()
|
|||
{
|
||||
string str="0o";
|
||||
ptr+=2;
|
||||
while(ptr<res.size() && OCT(res[ptr]))
|
||||
while(ptr<res.size() && is_oct(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
column+=str.length();
|
||||
if(str.length()<3)// "0o"
|
||||
|
@ -247,12 +306,12 @@ string lexer::num_gen()
|
|||
// generate dec number
|
||||
// dec number -> [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*)
|
||||
string str="";
|
||||
while(ptr<res.size() && DIGIT(res[ptr]))
|
||||
while(ptr<res.size() && is_dec(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
if(ptr<res.size() && res[ptr]=='.')
|
||||
{
|
||||
str+=res[ptr++];
|
||||
while(ptr<res.size() && DIGIT(res[ptr]))
|
||||
while(ptr<res.size() && is_dec(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
// "xxxx." is not a correct number
|
||||
if(str.back()=='.')
|
||||
|
@ -267,7 +326,7 @@ string lexer::num_gen()
|
|||
str+=res[ptr++];
|
||||
if(ptr<res.size() && (res[ptr]=='-' || res[ptr]=='+'))
|
||||
str+=res[ptr++];
|
||||
while(ptr<res.size() && DIGIT(res[ptr]))
|
||||
while(ptr<res.size() && is_dec(res[ptr]))
|
||||
str+=res[ptr++];
|
||||
// "xxxe(-|+)" is not a correct number
|
||||
if(str.back()=='e' || str.back()=='E' || str.back()=='-' || str.back()=='+')
|
||||
|
@ -352,23 +411,23 @@ void lexer::scan(const string& file)
|
|||
}
|
||||
}
|
||||
if(ptr>=res.size()) break;
|
||||
if(ID(res[ptr]))
|
||||
if(is_id(res[ptr]))
|
||||
{
|
||||
str=id_gen();
|
||||
u32 type=get_type(str);
|
||||
tokens.push_back({line,column,type?type:tok_id,str});
|
||||
}
|
||||
else if(DIGIT(res[ptr]))
|
||||
else if(is_dec(res[ptr]))
|
||||
{
|
||||
str=num_gen(); // make sure column is correct
|
||||
tokens.push_back({line,column,tok_num,str});
|
||||
}
|
||||
else if(STR(res[ptr]))
|
||||
else if(is_str(res[ptr]))
|
||||
{
|
||||
str=str_gen(); // make sure column is correct
|
||||
tokens.push_back({line,column,tok_str,str});
|
||||
}
|
||||
else if(SINGLE_OPERATOR(res[ptr]))
|
||||
else if(is_single_opr(res[ptr]))
|
||||
{
|
||||
str=res[ptr];
|
||||
++column;
|
||||
|
@ -387,7 +446,7 @@ void lexer::scan(const string& file)
|
|||
column+=str.length();
|
||||
tokens.push_back({line,column,get_type(str),str});
|
||||
}
|
||||
else if(CALC_OPERATOR(res[ptr]))
|
||||
else if(is_calc_opr(res[ptr]))
|
||||
{
|
||||
// get calculation operator
|
||||
str=res[ptr++];
|
||||
|
@ -396,7 +455,7 @@ void lexer::scan(const string& file)
|
|||
column+=str.length();
|
||||
tokens.push_back({line,column,get_type(str),str});
|
||||
}
|
||||
else if(NOTE(res[ptr]))// avoid note, after this process ptr will point to a '\n', so next loop line counter+1
|
||||
else if(res[ptr]=='#')// avoid note, after this process ptr will point to a '\n', so next loop line counter+1
|
||||
while(++ptr<res.size() && res[ptr]!='\n');
|
||||
else
|
||||
{
|
||||
|
@ -405,7 +464,7 @@ void lexer::scan(const string& file)
|
|||
die("invalid character 0x"+chrhex(c));
|
||||
}
|
||||
}
|
||||
tokens.push_back({line,column,tok_eof,"eof"});
|
||||
tokens.push_back({line,column,tok_eof,"<eof>"});
|
||||
res="";
|
||||
err.chkerr();
|
||||
}
|
||||
|
@ -415,5 +474,3 @@ void lexer::print()
|
|||
for(auto& tok:tokens)
|
||||
std::cout<<"("<<tok.line<<" | "<<rawstr(tok.str,128)<<")\n";
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_OPT_H__
|
||||
#define __NASAL_OPT_H__
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
@ -67,4 +66,3 @@ void optimize(ast& root)
|
|||
for(auto& i:root.child())
|
||||
calc_const(i);
|
||||
}
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_PARSE_H__
|
||||
#define __NASAL_PARSE_H__
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
@ -96,7 +95,7 @@ private:
|
|||
ast for_loop();
|
||||
ast forei_loop();
|
||||
ast iter_gen();
|
||||
ast conditional();
|
||||
ast cond();
|
||||
ast continue_expr();
|
||||
ast break_expr();
|
||||
ast ret_expr();
|
||||
|
@ -244,7 +243,7 @@ bool parse::check_special_call()
|
|||
bool parse::need_semi_check(const ast& node)
|
||||
{
|
||||
u32 type=node.type();
|
||||
if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional)
|
||||
if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_cond)
|
||||
return false;
|
||||
return !check_func_end(node);
|
||||
}
|
||||
|
@ -466,7 +465,7 @@ ast parse::expr()
|
|||
case tok_forindex:
|
||||
case tok_foreach:
|
||||
case tok_while: return loop(); break;
|
||||
case tok_if: return conditional(); break;
|
||||
case tok_if: return cond(); break;
|
||||
case tok_continue: return continue_expr(); break;
|
||||
case tok_break: return break_expr(); break;
|
||||
case tok_ret: return ret_expr(); break;
|
||||
|
@ -765,9 +764,9 @@ ast parse::definition()
|
|||
node.add(check_multi_scalar()?multi_scalar(false):calc());
|
||||
else
|
||||
node.add(calc());
|
||||
if(node[0].type()==ast_id && node[1].type()==ast_multi_scalar)
|
||||
if(node[0].type()==ast_id && node[1].type()==ast_tuple)
|
||||
die(node[1].line(),"one variable cannot accept too many values");
|
||||
else if(node[0].type()==ast_multi_id && node[1].type()==ast_multi_scalar && node[0].size()!=node[1].size())
|
||||
else if(node[0].type()==ast_multi_id && node[1].type()==ast_tuple && node[0].size()!=node[1].size())
|
||||
die(node[0].line(),"too much or lack values in multi-definition");
|
||||
return node;
|
||||
}
|
||||
|
@ -815,7 +814,7 @@ ast parse::multi_scalar(bool check_call_memory)
|
|||
tok_func,tok_var,tok_lcurve,
|
||||
tok_lbrace,tok_lbracket,tok_null
|
||||
};
|
||||
ast node(tokens[ptr].line,tokens[ptr].col,ast_multi_scalar);
|
||||
ast node(tokens[ptr].line,tokens[ptr].col,ast_tuple);
|
||||
match(tok_lcurve);
|
||||
while(!lookahead(tok_rcurve))
|
||||
{
|
||||
|
@ -846,7 +845,7 @@ ast parse::multi_assgin()
|
|||
node.add(check_multi_scalar()?multi_scalar(false):calc());
|
||||
else
|
||||
node.add(calc());
|
||||
if(node[1].type()==ast_multi_scalar
|
||||
if(node[1].type()==ast_tuple
|
||||
&& node[0].size()!=node[1].size())
|
||||
die(node[0].line(),"too much or lack values in multi-assignment");
|
||||
return node;
|
||||
|
@ -952,9 +951,9 @@ ast parse::iter_gen()
|
|||
}
|
||||
return node;
|
||||
}
|
||||
ast parse::conditional()
|
||||
ast parse::cond()
|
||||
{
|
||||
ast node(tokens[ptr].line,tokens[ptr].col,ast_conditional);
|
||||
ast node(tokens[ptr].line,tokens[ptr].col,ast_cond);
|
||||
ast ifnode(tokens[ptr].line,tokens[ptr].col,ast_if);
|
||||
match(tok_if);
|
||||
match(tok_lcurve);
|
||||
|
@ -1006,4 +1005,3 @@ ast parse::ret_expr()
|
|||
node.add(calc());
|
||||
return node;
|
||||
}
|
||||
#endif
|
||||
|
|
50
nasal_vm.h
50
nasal_vm.h
|
@ -1,5 +1,4 @@
|
|||
#ifndef __NASAL_VM_H__
|
||||
#define __NASAL_VM_H__
|
||||
#pragma once
|
||||
|
||||
#include <iomanip>
|
||||
#include <stack>
|
||||
|
@ -16,9 +15,11 @@ protected:
|
|||
var upvalr; // upvalue register
|
||||
var* canary; // avoid stackoverflow
|
||||
var* top; // stack top
|
||||
const f64* num_table;// const numbers, ref from codegen
|
||||
const string* str_table;// const symbols, ref from codegen
|
||||
std::vector<u32> imm; // immediate number
|
||||
|
||||
/* constants */
|
||||
const f64* cnum; // const numbers
|
||||
const string* cstr; // const symbols
|
||||
std::vector<u32> imm; // immediate number
|
||||
|
||||
/* garbage collector */
|
||||
gc ngc;
|
||||
|
@ -26,8 +27,8 @@ protected:
|
|||
var stack[STACK_DEPTH];
|
||||
|
||||
/* values used for debugger */
|
||||
const string* files; // ref from linker
|
||||
const opcode* bytecode; // ref from codegen
|
||||
const string* files;
|
||||
const opcode* bytecode;
|
||||
|
||||
void init(
|
||||
const std::vector<string>&,
|
||||
|
@ -128,7 +129,7 @@ public:
|
|||
vm():
|
||||
pc(0),localr(nullptr),memr(nullptr),funcr(nil),
|
||||
upvalr(nil),canary(nullptr),top(stack),
|
||||
num_table(nullptr),str_table(nullptr),
|
||||
cnum(nullptr),cstr(nullptr),
|
||||
ngc(pc,localr,memr,funcr,upvalr,canary,top,stack),
|
||||
files(nullptr),bytecode(nullptr),detail_info(false){}
|
||||
void run(
|
||||
|
@ -146,8 +147,8 @@ void vm::init(
|
|||
const std::vector<string>& argv)
|
||||
{
|
||||
ngc.init(strs,argv);
|
||||
num_table=nums.data();
|
||||
str_table=strs.data();
|
||||
cnum=nums.data();
|
||||
cstr=strs.data();
|
||||
bytecode=code.data();
|
||||
files=filenames.data();
|
||||
|
||||
|
@ -223,7 +224,7 @@ void vm::traceback()
|
|||
<<" 0x"<<std::hex<<std::setw(8)<<std::setfill('0')
|
||||
<<prev<<std::dec<<" "<<same<<" same call(s)\n";
|
||||
same=0;
|
||||
std::cout<<" "<<codestream(bytecode[p],p,num_table,str_table,files)<<"\n";
|
||||
std::cout<<" "<<codestream(bytecode[p],p,cnum,cstr,files)<<"\n";
|
||||
}
|
||||
// the first called place has no same calls
|
||||
}
|
||||
|
@ -360,7 +361,7 @@ inline void vm::o_loadu()
|
|||
}
|
||||
inline void vm::o_pnum()
|
||||
{
|
||||
(++top)[0]={vm_num,num_table[imm[pc]]};
|
||||
(++top)[0]={vm_num,cnum[imm[pc]]};
|
||||
}
|
||||
inline void vm::o_pnil()
|
||||
{
|
||||
|
@ -396,6 +397,8 @@ inline void vm::o_newf()
|
|||
if(localr)
|
||||
{
|
||||
func.upval=funcr.func().upval;
|
||||
// function created in the same local scope shares one closure
|
||||
// so this size & stk setting has no problem
|
||||
var upval=(upvalr.type==vm_nil)?ngc.alloc(vm_upval):upvalr;
|
||||
upval.upval().size=funcr.func().lsize;
|
||||
upval.upval().stk=localr;
|
||||
|
@ -405,7 +408,7 @@ inline void vm::o_newf()
|
|||
}
|
||||
inline void vm::o_happ()
|
||||
{
|
||||
top[-1].hash().elems[str_table[imm[pc]]]=top[0];
|
||||
top[-1].hash().elems[cstr[imm[pc]]]=top[0];
|
||||
--top;
|
||||
}
|
||||
inline void vm::o_para()
|
||||
|
@ -465,7 +468,7 @@ inline void vm::o_lnk()
|
|||
}
|
||||
|
||||
#define op_calc_const(type)\
|
||||
top[0]={vm_num,top[0].tonum() type num_table[imm[pc]]};
|
||||
top[0]={vm_num,top[0].tonum() type cnum[imm[pc]]};
|
||||
|
||||
inline void vm::o_addc(){op_calc_const(+);}
|
||||
inline void vm::o_subc(){op_calc_const(-);}
|
||||
|
@ -473,7 +476,7 @@ inline void vm::o_mulc(){op_calc_const(*);}
|
|||
inline void vm::o_divc(){op_calc_const(/);}
|
||||
inline void vm::o_lnkc()
|
||||
{
|
||||
top[0]=ngc.newstr(top[0].tostr()+str_table[imm[pc]]);
|
||||
top[0]=ngc.newstr(top[0].tostr()+cstr[imm[pc]]);
|
||||
}
|
||||
|
||||
#define op_calc_eq(type)\
|
||||
|
@ -493,7 +496,7 @@ inline void vm::o_lnkeq()
|
|||
}
|
||||
|
||||
#define op_calc_eq_const(type)\
|
||||
top[0]=memr[0]={vm_num,memr[0].tonum() type num_table[imm[pc]&0x7fffffff]};\
|
||||
top[0]=memr[0]={vm_num,memr[0].tonum() type cnum[imm[pc]&0x7fffffff]};\
|
||||
memr=nullptr;\
|
||||
top-=(imm[pc]>>31);
|
||||
|
||||
|
@ -503,7 +506,7 @@ inline void vm::o_muleqc(){op_calc_eq_const(*);}
|
|||
inline void vm::o_diveqc(){op_calc_eq_const(/);}
|
||||
inline void vm::o_lnkeqc()
|
||||
{
|
||||
top[0]=memr[0]=ngc.newstr(memr[0].tostr()+str_table[imm[pc]&0x7fffffff]);
|
||||
top[0]=memr[0]=ngc.newstr(memr[0].tostr()+cstr[imm[pc]&0x7fffffff]);
|
||||
memr=nullptr;
|
||||
top-=(imm[pc]>>31);
|
||||
}
|
||||
|
@ -558,7 +561,7 @@ inline void vm::o_grt(){op_cmp(>);}
|
|||
inline void vm::o_geq(){op_cmp(>=);}
|
||||
|
||||
#define op_cmp_const(type)\
|
||||
top[0]=(top[0].tonum() type num_table[imm[pc]])?one:zero;
|
||||
top[0]=(top[0].tonum() type cnum[imm[pc]])?one:zero;
|
||||
|
||||
inline void vm::o_lessc(){op_cmp_const(<);}
|
||||
inline void vm::o_leqc(){op_cmp_const(<=);}
|
||||
|
@ -671,9 +674,9 @@ inline void vm::o_callh()
|
|||
var val=top[0];
|
||||
if(val.type!=vm_hash)
|
||||
vm_error("must call a hash");
|
||||
top[0]=val.hash().get_val(str_table[imm[pc]]);
|
||||
top[0]=val.hash().get_val(cstr[imm[pc]]);
|
||||
if(top[0].type==vm_none)
|
||||
vm_error("member \""+str_table[imm[pc]]+"\" does not exist");
|
||||
vm_error("member \""+cstr[imm[pc]]+"\" does not exist");
|
||||
if(top[0].type==vm_func)
|
||||
top[0].func().local[0]=val;// 'me'
|
||||
}
|
||||
|
@ -746,7 +749,7 @@ inline void vm::o_callfh()
|
|||
|
||||
for(auto& i:func.keys)
|
||||
{
|
||||
const string& key=str_table[i.first];
|
||||
auto& key=cstr[i.first];
|
||||
if(hash.count(key))
|
||||
local[i.second]=hash[key];
|
||||
else if(local[i.second].type==vm_none)
|
||||
|
@ -874,8 +877,8 @@ inline void vm::o_mcallh()
|
|||
var hash=top[0]; // mcall hash, reserved on stack to avoid gc
|
||||
if(hash.type!=vm_hash)
|
||||
vm_error("must call a hash");
|
||||
nas_hash& ref=hash.hash();
|
||||
const string& str=str_table[imm[pc]];
|
||||
auto& ref=hash.hash();
|
||||
auto& str=cstr[imm[pc]];
|
||||
memr=ref.get_mem(str);
|
||||
if(!memr) // create a new key
|
||||
{
|
||||
|
@ -1117,4 +1120,3 @@ mcallh: exec_nodie(o_mcallh); // -0
|
|||
ret: exec_nodie(o_ret ); // -2
|
||||
#endif
|
||||
}
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
# wave collapse function 2022/4/10
|
||||
# by ValKmjolnir
|
||||
srand();
|
||||
var interval=1/60;
|
||||
var interval=1/120;
|
||||
var table=[
|
||||
# c ,w,a,s,d
|
||||
["═",0,1,0,1],
|
||||
|
|
Loading…
Reference in New Issue