added .moo (parser definitions) to Mercury extension list

This commit is contained in:
Sebastian Godelet
2014-04-06 20:26:28 +02:00
parent a620d45635
commit fe183c07f5
5 changed files with 205 additions and 42 deletions

72
samples/Mercury/expr.moo Normal file
View File

@@ -0,0 +1,72 @@
:- module expr.
:- interface.
:- import_module char, int, list.
:- type token
---> ('+')
; ('-')
; ('*')
; ('/')
; num(int)
; ('(')
; (')')
; eof
.
:- parse(exprn/1, token, eof, xx, in, out).
:- pred scan(list(char), list(token)).
:- mode scan(in, out) is det.
:- implementation.
:- import_module string, require.
:- rule exprn(int).
exprn(Num) ---> exprn(A), [+], term(B), { Num = A + B }.
exprn(Num) ---> exprn(A), [-], term(B), { Num = A - B }.
exprn(Num) ---> term(Num).
:- rule term(int).
term(Num) ---> term(A), [*], factor(B), { Num = A * B }.
term(Num) ---> term(A), [/], factor(B), { Num = A // B }.
term(Num) ---> factor(Num).
:- rule factor(int).
factor(Num) ---> ['('], exprn(Num), [')'].
factor(Num) ---> [num(Num)].
scan(Chars, Toks) :-
scan(Chars, [], Toks0),
list__reverse(Toks0, Toks).
:- pred scan(list(char), list(token), list(token)).
:- mode scan(in, in, out) is det.
scan([], Toks, [eof|Toks]).
scan([C|Cs], Toks0, Toks) :-
( char__is_whitespace(C) ->
scan(Cs, Toks0, Toks)
; char__is_digit(C) ->
takewhile(char__is_digit, [C|Cs], Digits, Rest),
string__from_char_list(Digits, NumStr),
Num = string__det_to_int(NumStr),
scan(Rest, [num(Num)|Toks0], Toks)
; C = ('+') ->
scan(Cs, ['+'|Toks0], Toks)
; C = ('-') ->
scan(Cs, ['-'|Toks0], Toks)
; C = ('*') ->
scan(Cs, ['*'|Toks0], Toks)
; C = ('/') ->
scan(Cs, ['/'|Toks0], Toks)
; C = ('(') ->
scan(Cs, ['('|Toks0], Toks)
; C = (')') ->
scan(Cs, [')'|Toks0], Toks)
;
error("expr: syntax error in input")
).

View File

@@ -0,0 +1,5 @@
@program toy:wind
this.wound = this.wound + 2;
player:tell("You wind up the ", this.name,".");
player.location:announce(player.name, " winds up the ", this.name,".");
.

19
samples/Moocode/toy.moo Normal file
View File

@@ -0,0 +1,19 @@
@verb toy:do_the_work this none this
@program toy:do_the_work
if (this.wound)
if ($object_utils:isa(this.location,$room))
this.location:announce_all(this.name," ", this:continue_msg());
this.wound = this.wound - 1;
if (this.wound)
fork (15)
this:do_the_work();
endfork
else
this.location:announce_all(this.name, " ", this:wind_down_msg());
endif
endif
if (this.wound < 0)
this.wound = 0;
endif
endif
.