在Prolog中实现一个简单的C语言?

Has*_*bug 6 interpreter declarative prolog dcg

我是prolog的新手,所以这对我来说是一个很大的挑战.我应该在Prolog中实现一个简单的C语言.

the ultimate goal is to be able to execute something like this:
?- run([begin,a,:=,10,while,a,>,5,begin,write,a,a,:=,a,-,1,end,end]).

and get: 
10 
9
8
7
6 
yes
Run Code Online (Sandbox Code Playgroud)

但是,我陷入了第一步.这是我迄今取得的成就.超出本地堆栈!

statement(Vars,_Vars) --> assign(Vars,_Vars).
statement(Vars,Vars2) --> statement(Vars,Vars1), statement(Vars1,Vars2). 

assign(Vars,_Vars) --> default_assign(Vars,_Vars).
assign(Vars,_Vars) --> simple_assign(Vars,_Vars).

% a //default value 0
default_assign(Vars,_Vars) --> 
    var_name(Var_Name),
    {update_vars([Var_Name,0],Vars,_Vars)}.

% a = 0
simple_assign(Vars,_Vars) --> 
    var_name(Var_Name),[=],var_value(Var_Value),
    {update_vars([Var_Name,Var_Value],Vars,_Vars)}.

% a = b
simple_assign(Vars,_Vars) --> 
    var_name(Var_Name1),[=],var_name(Var_Name2),
    {
    update_vars([Var_Name1,Var_Value],Vars,_Vars)
    }.

var_name(Var_Name) --> [Var_Name],{\+number(Var_Name2)}.    
var_value(Var_Value) -->[Var_Value],{number(Var_Value)}.

% found match, update
update_vars(Var,Vars,_Vars):-
    member(Var,Vars),
    update(Var,Vars,_Vars),
    _Vars\==[].
% no match, append
update_vars(Var,Vars,_Vars):-
    \+member(Var,Vars),
    append(Var,Vars,_Vars).

update([Name,Value],[],[]).
update([Name,Value],[[Name,Old_Value]|T1],[[Name,Value]|T2]):-
    update([Name,Value],T1,T2).
update([Name,Value],[[Name1,Value1]|T1],[[Name1,Value1]|T2]):-
    [Name,Value]\=[Name1,Value1],
    update([Name,Value],T1,T2).

append([Name,Value],[],[[Name,Value]]).
append([Name,Value],[H|T1],[H|T2]):-
    append([Name,Value],T1,T2).
Run Code Online (Sandbox Code Playgroud)

这是我的逻辑.首先,我希望能够使用列表(这就是我解释它的方式 - - !),因此语法结构非常重要.而且我也在考虑以[[Name,Value],[a,1],[b,2] ...]的形式使用变量列表'Vars',以及更新版本 - '_Vars'.所以我可以把它传递给其他语句,比如while循环和写.

statement(Vars,Vars2) --> statement(Vars,Vars1), statement(Vars1,Vars2).
% this seems wrong...
Run Code Online (Sandbox Code Playgroud)

但是......看起来逻辑从一开始就是错误的.:\下面是简化版.如果你能在这里帮助我,我将非常感激.而且我真的希望我不会在圣诞节时带着它.TT

statement --> assign.
statement --> statement, statement.

assign --> simple_assign.
assign --> default_assign.

default_assign --> 
    var_name(Var_Name).
simple_assign --> 
    var_name,[=],var_value.

var_name --> 
    [Var_Name],{\+number(Var_Name)}.    
var_value -->
    [Var_Value],{number(Var_Value)}.
Run Code Online (Sandbox Code Playgroud)

Use*_*ser 2

这就是我的做法:

  1. 将源代码转化为抽象语法树

    begin 
      a := 1
      while a < 5
      begin
        a := a + 1;
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)

    变成

    statements([
        assign(a, number(1)),
        while(greater(variable(a), number(5))), 
              statements([
                  assign(a, plus(variable(a), number(1)))
                         ])
             )
               ])
    
    Run Code Online (Sandbox Code Playgroud)
  2. 为它构建一个解释器。

    有各种各样的翻译。最简单的一种是普通解释器。我将从以下内容开始:

    interpret(number(N), State, N, State).
    interpret(assign(Variable, Statement), State, Value, NewState) :- 
        interpret(Statement, State, Value, NewState1), 
        assignVariable(Variable, Value, NewState1, NewState).
    
    Run Code Online (Sandbox Code Playgroud)