-module(pparser).
-export([start/1]).
-import(io,[fwrite/1,format/2]).
-import(sfile,[load/1,unload/1,readline/1]).
-import(string,[len/1,substr/3,to_lower/1,to_upper/1,strip/1,tokens/2,join/2]).
-import(ets,[new/2,insert/2,delete/1,lookup/2]).
-import(qsort,[qsort3/1]).
-import(lists,[reverse/1,concat/1]).
-vsn(0.1005).
-author({deepfuturelx@gmail.com}).
%解释执行源代码
%遵守LGPL协议
start(Sfilename)->%启动解释器
fwrite("Poles 0.1005 \nContact us:deepfuturelx@gmail.com\nload.....~n"),
try load(Sfilename) of
Sf->
prestart(Sfilename),
try read(Sf)
catch
{error,Why}->
format("~s~n",[Why]);
{runerr,Runwhy}->
format("~s~n",[Runwhy])
after
preclose(),
unload(Sf)
end
catch
err->format("load ~s error~n",[Sfilename])
end.
prestart(Sfilename)->%解析前运行
erase(),%清空符号表
getcurln(),
format("load ~s finished.~n",[Sfilename]).
preclose()->%关闭前运行
erase().%清空符号表
read(Sf)->%读源代码
case readline(Sf) of
eof->format("run finished~n",[]);
Data->
begin
try parse(Data)
catch
{error,Why}->throw({error,Why});
{runerr,Runwhy}->throw({runerr,Runwhy})
end
end,
read(Sf)
end.
parse(Data)->%解析一行
inccurln(),
Line=strip(substr(Data,1,len(Data)-1)),
case substr(Line,1,1)=:="#" of
true->%注释使用#
notes(Line);
false->%非注释,执行
begin
Sline=tokens(Line,"\t"),
try run(Sline)
catch
{error,Why}->throw({error,Why});
{runerr,Runwhy}->throw({runerr,Runwhy})
end
end
end.
run(Spline)->%运行一行代码
%format("~p~n",[Spline]),
try runinstruction(list_to_tuple(Spline))
catch
{error,Why}->throw({error,concat([" line ",getcurln()," ~"])++join(Spline," ")++"|====>runtime error:"++Why});
{runerr,Runwhy}->throw({runerr,concat([" line ",getcurln()," ~"])++join(Spline," ")++"|====>run error:"++Runwhy})
end.
runinstruction(Instruction)-> %分析并执行指令
try Instruction of
{"list",Source,Target}->modisymbol({Source,list,Target,null});%列表变量声明
{"list",Source}->modisymbol({Source,list,[],null});%列表变量赋值并声明
{"var",Source,Target}->modisymbol({Source,var,Target,null});%标量赋值声明
{"var",Source}->modisymbol({Source,var,null,null});%标量声明
{"mov",Source,Target}->assign({Source,Target});%赋值
{"pushlist",Source,Target}->pushlist({Source,Target});%push 列表 列表
{"push",Source,Target}->push({Source,Target});%push 元素 列表
{"qsort",Source,Target}->qsort({Source,Target});%qsort 列表
{"pop",Source,Target}->pop({Source,Target});%pop 列表
{"pop",Source,Target,"del"}->pop({Source,Target},del);%pop and del 列表首
{"say",Source}->say({Source});%带回车输出
{"print",Source}->print({Source});%输出
{}->{}%空行
catch
{error,Why}->throw({error,Why});
{runerr,Runwhy}->throw({runerr,Runwhy})
end.
notes(Sline)->Sline.
newsysinfo(poles_symbol)->%
new(poles_symbol,[set,named_table]).
delsysinfo(poles_symbol)->%
delete(poles_symbol).
modisymbol({Name,Type,Value,Flag})->%符号表修改符号
put(Name,{Name,Type,Value,Flag}).
assign({Value,Name})->%赋值
case findsymbol(Name) of
false->throw({runerr,Name++" not defined"});
{_,Type,_,SFlag}->
Svalue=eval(Value),
modisymbol({Name,Type,Svalue,SFlag})
end.
say({Name})->%带回车输出
case findsymbol(Name) of
false->
Value=eval(Name),
format("~p~n",[Value]);
{_,_,Value,_}->format("~p~n",[Value])
end.
print({Name})->%输出
case findsymbol(Name) of
false->
Value=eval(Name),
format("~p",[Value]);
{_,_,Value,_}->format("~p",[Value])
end.
push({Value,Name})->%在列表首加入元素
case findsymbol(Name) of
false->throw({runerr,Name++" not defined"});
{_,Type,SValue,SFlag}->modisymbol({Name,Type,[eval(Value)|SValue],SFlag})
end.
pushlist({Value,Name})->%在列表首加入列表元素
case findsymbol(Name) of
false->throw({runerr,Name++" not defined"});
{_,Type,SValue,SFlag}->modisymbol({Name,Type,eval(Value)++SValue,SFlag})
end.
pop({Sname,Dname})->%在列表首取出元素
case findsymbol(Sname) of
false->throw({runerr,Dname++"not defined"});
{_,Type,[Popvalue|_Svalue],Sflag}->
case findsymbol(Dname) of
false->throw({runerr,Dname++" not defined"});
{_,_,_,_}->modisymbol({Dname,Type,Popvalue,Sflag})
end
end.
pop({Sname,Dname},del)->%在列表首取出并删除元素
case findsymbol(Sname) of
false ->throw({runerr,Dname++"not defined"});
{_,Type,[Popvalue|Svalue],Sflag}->
case findsymbol(Dname) of
false->throw({runerr,Dname++" not defined"});
{_,_,_,_}->
modisymbol({Sname,Type,Svalue,Sflag}),
modisymbol({Dname,Type,Popvalue,Sflag})
end
end.
trans(ErlTokens,Stk,NewErlTokens)->%处理表达式中的变量
[Stoken|Et]=ErlTokens,
case Stoken of
{atom,_,Name}->%变量
NewEtoken=[{var,1,list_to_atom(to_upper(atom_to_list(Name)))}|NewErlTokens],
case findsymbol(atom_to_list(Name)) of
false->throw({runerr,atom_to_list(Name)++" not defined"});
{_Name,Type,Val,_Flag}->
case Type of
list->
NewVal=concat([Stk,to_upper(atom_to_list(Name)),"=",concat(io_lib:format("~p",[Val])),","]);
_Other->NewVal=concat([Stk,to_upper(atom_to_list(Name)),"=",Val,","])
end,
trans(Et,NewVal,NewEtoken)
end;
{dot,Flag}->%结束
NewEtoken=[{dot,Flag}|NewErlTokens],
Etoken=reverse(NewEtoken),
{ok,VarEtoken,_}=erl_scan:string(Stk),%转换变量声明为erlang内部的方式VarEtoken
EndToken=addexpress(VarEtoken,Etoken),%将erlang内部方式声明的变量加入到现有表达式中
EndToken;
Val->%普通运算
NewEtoken=[Val|NewErlTokens],
trans(Et,Stk,NewEtoken)
end.
addexpress(VarEtoken,Etoken)->%将erlang内部方式声明的变量加入到现有表达式中
case VarEtoken of
[]->Etoken;
Val->
EndEtoken=Val++Etoken,
EndEtoken
end.
eval(S) ->%计算表达式
case findsymbol(S) of
{_,_,Value,_}->Value;
false->
begin
{ok,ErlTokens,_}=erl_scan:string(S++"."),
SErlTokens=trans(ErlTokens,[],[]),
{ok,ErlAbsForm}=erl_parse:parse_exprs(SErlTokens),
{value,Value,_}=erl_eval:exprs(ErlAbsForm,[]),
Value
end
end.
qsort({Sname,Dname})->%排序list
case findsymbol(Sname) of
false->throw({runerr,Dname++"not defined"});
{_,Type,Svalue,Sflag}->
case findsymbol(Dname) of
false->throw({runerr,Dname++" not defined"});
{_,_,_,_}->
Sortvalue=qsort3(Svalue),
modisymbol({Dname,Type,Sortvalue,Sflag})
end
end.
getcurln()->%取得当前行号
begin
case findsymbol(sys__line) of
false->modisymbol({sys__line,runsys,1,null}),1;
{sys__line,runsys,Line,null}->Line
end
end.
inccurln()->%当前行号++
Curline=getcurln()+1,
modisymbol({sys__line,runsys,Curline,null}).
findsymbol(Name)->%找到符号,并返回值
case get(Name) of
undefined->false;
Val->Val
end.
-module(sfile).
-export([load/1,readline/1,unload/1]).
-import(io,[get_line/2,atom/0]).
-import(file,[open/2,close/1]).
-vsn(0.1001).
-author({deepfuture}).
%源代码文件操作
%load读取源文件,readline读取一行,unload关闭源文件
load(Sfilename)->
case open(Sfilename,read) of
{ok,Sf}->Sf;
{error,Why}->throw(err)
end.
readline(Sf)->get_line(Sf,"").
unload(Sf)->close(Sf).
% Copyright (c) 2010 the authors listed at the following URL, and/or
% the authors of referenced articles or incorporated external code:
% http://en.literateprograms.org/Quicksort_(Erlang)?action=history&offset=20060711142841
%
% Permission is hereby granted, free of charge, to any person obtaining
% a copy of this software and associated documentation files (the
% "Software"), to deal in the Software without restriction, including
% without limitation the rights to use, copy, modify, merge, publish,
% distribute, sublicense, and/or sell copies of the Software, and to
% permit persons to whom the Software is furnished to do so, subject to
% the following conditions:
%
% The above copyright notice and this permission notice shall be
% included in all copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
% IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
% CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
% TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
% SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%
% Retrieved from: http://en.literateprograms.org/Quicksort_(Erlang)?oldid=6960
-module(qsort).
-export([qsort1/1, qsort2/1, qsort3/1]).
qsort1([]) ->
[];
qsort1([H | T]) ->
qsort1([ X || X <- T, X < H ]) ++ [H] ++ qsort1([ X || X <- T, X >= H ]).
qsort2([]) ->
[];
qsort2([H | T]) ->
{Less, Equal, Greater} = part(H, T, {[], [H], []}),
qsort2(Less) ++ Equal ++ qsort2(Greater).
part(_, [], {L, E, G}) ->
{L, E, G};
part(X, [H | T], {L, E, G}) ->
if
H < X ->
part(X, T, {[H | L], E, G});
H > X ->
part(X, T, {L, E, [H | G]});
true ->
part(X, T, {L, [H | E], G})
end.
qsort3([]) ->
[];
qsort3([H | T]) ->
qsort3_acc([H | T], []).
qsort3_acc([], Acc) ->
Acc;
qsort3_acc([H | T], Acc) ->
part_acc(H, T, {[], [H], []}, Acc).
part_acc(_, [], {L, E, G}, Acc) ->
qsort3_acc(L, (E ++ qsort3_acc(G, Acc)));
part_acc(X, [H | T], {L, E, G}, Acc) ->
if
H < X ->
part_acc(X, T, {[H | L], E, G}, Acc);
H > X ->
part_acc(X, T, {L, E, [H | G]}, Acc);
true ->
part_acc(X, T, {L, [H | E], G}, Acc)
end.
一、将代码开源(遵守LGPL协议)
当前版本的语言规范
代码以三指令和四指令为主,以TAB分割每行代码的元素
list 变量名 声明列表变量
var 变量名 声明单变量
push 表达式 列表变量 为将表达式的值放入列表首部
pop 列表变量 变量 为获得列表首部的值并放入变量
pop 列表变量 变量 del 为将列表首部的变量弹出放入变量
以#开头表示注释,注释必须单独占一行
pushlist 列表变量 列表变量 为将列表放入列表首部
say 表达式 带回车输出
print 表达式 输出
mov 表达式 变量 赋值到变量
表达式计算支持erlang格式的标准表达式,包括列表计算,不支持表达式直接调用erlang的函数
四、脚本代码示例
#test2.po
#代码以三指令和四指令为主,以TAB分割每行代码的元素
list a
list b
pushlist [88,89] a
#取余
push 5 rem 2 b
#a++[90,91]和a--[89]完成2个列表的计算
pushlist a++[90,91] b
pushlist a--[89] b
say "===="
say b
任务
1、调试和完善现在指令
2、增加部分顺序执行指令
3、尝试编写对条件语句的解析
4、完成函数
5、继续并行计算架构代码
三、当前版本的语言规范
代码以三指令和四指令为主,以TAB分割每行代码的元素
list 变量名 声明列表变量
var 变量名 声明单变量
push 表达式 列表变量 为将表达式的值放入列表首部
pop 列表变量 变量 为获得列表首部的值并放入变量
pop 列表变量 变量 del 为将列表首部的变量弹出放入变量
以#开头表示注释,注释必须单独占一行
pushlist 列表变量 列表变量 为将列表放入列表首部
say 表达式 带回车输出
print 表达式 输出
mov 表达式 变量 赋值到变量
表达式计算支持erlang格式的标准表达式,包括列表计算,不支持表达式直接调用erlang的函数
四、脚本代码示例
1、
#test2.po
#代码以三指令和四指令为主,以TAB分割每行代码的元素
list a
list b
pushlist [88,89] a
#取余
push 5 rem 2 b
#a++[90,91]和a--[89]完成2个列表的计算
pushlist a++[90,91] b
pushlist a--[89] b
say "===="
say b
2、
进入erlang,将pparser.beam等目录下的beam文件列入erlang的搜索目录,然后运行脚本
pparser:start("脚本文件名称").
比如:
1>pparser:start("test2.po").
Poles 0.1005
Contact us:deepfuturelx@gmail.com
load.....
load ../test/test2.po finished.
"===="
[88,88,89,90,91,1]
run finished
ok
本文介绍了 Poles 解释器的实现原理与基本指令集,该解释器支持列表操作、变量赋值、输出等功能,采用 Erlang 编写,遵循 LGPL 协议开源。
2437

被折叠的 条评论
为什么被折叠?



