toplevel.pl 2.51 KB
Newer Older
Thierry Martinez's avatar
Thierry Martinez committed
1
2
3
:- module(
  toplevel,
  [
Thierry Martinez's avatar
Thierry Martinez committed
4
    execute_command/1,
Thierry Martinez's avatar
Thierry Martinez committed
5
    toplevel/0,
Thierry Martinez's avatar
Thierry Martinez committed
6
    quit/0,
Thierry Martinez's avatar
Thierry Martinez committed
7
8
    command/1,
    prompt/1
Thierry Martinez's avatar
Thierry Martinez committed
9
10
  ]).

Thierry Martinez's avatar
Thierry Martinez committed
11

Thierry Martinez's avatar
Thierry Martinez committed
12
13
14
15
16
17
18
19
toplevel :-
  loop.


loop :-
  repeat,
  \+ read_execute_print.

Thierry Martinez's avatar
Thierry Martinez committed
20

Thierry Martinez's avatar
Thierry Martinez committed
21
read_execute_print :-
22
  set_counter(warnings, 0),
Thierry Martinez's avatar
Thierry Martinez committed
23
  read_command(Command),
Thierry Martinez's avatar
Thierry Martinez committed
24
25
26
27
28
29
30
31
32
  (
    Command = end_of_file
  ->
    nl,
    quit
  ;
    execute_command(Command)
  ).

Thierry Martinez's avatar
Thierry Martinez committed
33
34
35

:- dynamic(prompt/1).

Thierry Martinez's avatar
Thierry Martinez committed
36

Thierry Martinez's avatar
Thierry Martinez committed
37
38
prompt('biocham: ').

Thierry Martinez's avatar
Thierry Martinez committed
39

Thierry Martinez's avatar
Thierry Martinez committed
40
41
42
43
set_prompt(NewPrompt) :-
  retract(prompt(_OldPrompt)),
  asserta(prompt(NewPrompt)).

Thierry Martinez's avatar
Thierry Martinez committed
44

Thierry Martinez's avatar
Thierry Martinez committed
45
46
read_command(Command) :-
  prompt(Prompt),
Thierry Martinez's avatar
Thierry Martinez committed
47
48
  read_history('', '', [], Prompt, Command, VariableNames),
  name_variables_and_anonymous(Command, VariableNames).
Thierry Martinez's avatar
Thierry Martinez committed
49

Thierry Martinez's avatar
Thierry Martinez committed
50
51
52
53
54
55
56
57
58
59
60

execute_command(Command) :-
  catch(
    (
      command(Command)
    ->
      true
    ;
      throw(error(prolog_failure))
    ),
    Exception,
61
    print_message(error, Exception)
Thierry Martinez's avatar
Thierry Martinez committed
62
63
  ).

Thierry Martinez's avatar
Thierry Martinez committed
64

65
66
prolog:message(error(unknown_command(Command))) -->
  ['Unknown command: ~p'-[Command]].
Thierry Martinez's avatar
Thierry Martinez committed
67

68
69
prolog:message(error(prolog_failure)) -->
  ['Prolog failure'].
Thierry Martinez's avatar
Thierry Martinez committed
70

71
72
prolog:message(error(Exception)) -->
   ['Uncaught exception: ~p'-[Exception]].
Thierry Martinez's avatar
Thierry Martinez committed
73

Thierry Martinez's avatar
Thierry Martinez committed
74

Thierry Martinez's avatar
Thierry Martinez committed
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
check_types(Command, ArgumentTypes, NewCommand) :-
  Command =.. [Functor | Arguments],
  findall(
    NewArgument,
    (
      nth0(Index, Arguments, Argument),
      nth0(Index, ArgumentTypes, ArgumentType),
      (
        var(ArgumentType)
      ->
        NewArgument = Argument
      ;
        catch(
          (
            check_type(ArgumentType, Argument, NewArgument)
          ->
            true
          ;
            throw(error(failure))
          ),
          error(Type),
          throw(error(invalid_type(Argument, Type)))
        )
      )
    ),
    NewArguments
  ),
  NewCommand =.. [Functor | NewArguments].


Thierry Martinez's avatar
Thierry Martinez committed
105
command(Command) :-
Thierry Martinez's avatar
Thierry Martinez committed
106
  functor(Command, Functor, Arity),
Thierry Martinez's avatar
Thierry Martinez committed
107
  (
Thierry Martinez's avatar
Thierry Martinez committed
108
109
110
111
112
    (
      predicate_info(Functor/Arity, ArgumentTypes, yes, _)
    ->
      Command0 = Command
    ;
Thierry Martinez's avatar
Thierry Martinez committed
113
114
      between(1, Arity, Arity0),
      predicate_info(Functor/Arity0, ArgumentTypes, variantargs, _)
Thierry Martinez's avatar
Thierry Martinez committed
115
116
    ->
      Command =.. [Functor | Arguments],
Thierry Martinez's avatar
Thierry Martinez committed
117
118
119
120
121
      PrefixLength is Arity0 - 1,
      length(Prefix, PrefixLength),
      append(Prefix, Tail, Arguments),
      append(Prefix, [Tail], NewArguments),
      Command0 =.. [Functor | NewArguments]
Thierry Martinez's avatar
Thierry Martinez committed
122
    )
Thierry Martinez's avatar
Thierry Martinez committed
123
  ->
Thierry Martinez's avatar
Thierry Martinez committed
124
    check_types(Command0, ArgumentTypes, NewCommand),
Thierry Martinez's avatar
Thierry Martinez committed
125
    NewCommand
Thierry Martinez's avatar
Thierry Martinez committed
126
  ;
Thierry Martinez's avatar
Thierry Martinez committed
127
128
129
130
131
132
133
    (
      Command = (_ => _)
    ;
      Command = (_ <=> _)
    ;
      Command = (_ for _)
    )
Thierry Martinez's avatar
Thierry Martinez committed
134
  ->
Thierry Martinez's avatar
Thierry Martinez committed
135
    command(add_reaction(Command))
Thierry Martinez's avatar
Thierry Martinez committed
136
137
  ;
    throw(error(unknown_command(Functor/Arity)))
Thierry Martinez's avatar
Thierry Martinez committed
138
139
  ).

Thierry Martinez's avatar
Thierry Martinez committed
140

Thierry Martinez's avatar
Thierry Martinez committed
141
142
quit :-
  biocham_command,
Thierry Martinez's avatar
Thierry Martinez committed
143
  doc('quits the interpreter.'),
Thierry Martinez's avatar
Thierry Martinez committed
144
  halt.