-
Notifications
You must be signed in to change notification settings - Fork 0
/
metaII.pl
87 lines (73 loc) · 2.25 KB
/
metaII.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use strict;
use warnings;
sub say {
print(@_, "\n");
}
our @stack = ();
our $program;
our $choice;
our $sequence;
our $primary;
our $rule;
our $id;
our $string;
our $output;
my $res;
$string = qr{
('[^']*')
}xm;
$output = qr{
\{ \s*
(?: \s*
\$ (?{say "io.write(_input)"})
|
\s* $string (?{say "io.write(", $^N, ")"})
)*
\s*
\} (?{say 'io.write("\\n")'}) \s*
}xm;
$id = qr{
([\w][\w\d]*)
}xm;
$primary = qr{
(?: $string (?{say "_run.testSTR($^N)"})
| $id (?{say($^N, "()")})
| \.id (?{say "local _input = _run.parseID()"})
| \.number (?{say "local _input = _run.parseNUM()"})
| \.string (?{say "local _input = _run.parseSTR()"})
| \.empty (?{say "_switch = true"})
| \( \s* (??{our $choice}) \s* \)
| \* \s* (?{say "repeat -- repetition --"})
(??{our $primary}) (?{say "until not _switch -- repetition (end)"})
\s* (?{say "_switch = true "}))
}xm;
$sequence = qr{ \s*
(?{say"repeat -- sequence"})
(?: $primary (?{say "if not _switch then break end"})| $output)
(?: \s* (?: $primary (?{say "if not _switch then error() end"}) | $output ))*
(?{say"until true -- sequence (end)"})
}xm;
$choice = qr{ (?{say"repeat -- choice --"})
$sequence (?:\s* \| (?{say"if _switch then break end"}) \s* $sequence)* \s*
(?{say"until true -- choice (end)"})
}xm;
$rule = qr{
$id (?{push(@stack, $^N); say("function ", $^N, "()")}) \s+
= \s+
$choice \s*
; (?{say "end -- (", (pop(@stack)), ')' })
}xm;
$program = qr/^ \.syntax \s+
$id (?{ push(@stack, $^N); say('local _run = require("runtime")')}) \s+
(?: \s* $rule)* \s*
\.end (?{say(pop(@stack), "()")})
$/mx;
my $bootstrap;
my $a;
if ($a=shift){
local $/=undef;
open FILE, $a or die "Couldn't open file: $!";
$bootstrap= <FILE>;
close FILE;
}
($bootstrap =~ /$program/)