用erlang写的一个在erlang上跑的脚本语言-LGPL协议

阅读更多
-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({[email protected]}).
%解释执行源代码
%遵守LGPL协议

start(Sfilename)->%启动解释器
fwrite("Poles 0.1005 \nContact us:[email protected]\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:[email protected]
load.....
load ../test/test2.po finished.
"===="
[88,88,89,90,91,1]
run finished
ok

 

你可能感兴趣的:(Erlang,脚本,Gmail)