aboutsummaryrefslogtreecommitdiff
path: root/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'interpreter')
-rw-r--r--interpreter/Elymas.pm36
-rw-r--r--interpreter/ElymasGlobal.pm57
2 files changed, 78 insertions, 15 deletions
diff --git a/interpreter/Elymas.pm b/interpreter/Elymas.pm
index 20f8c36..eb514fa 100644
--- a/interpreter/Elymas.pm
+++ b/interpreter/Elymas.pm
@@ -7,7 +7,7 @@ require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(
popInt popString popArray arrayAccess $quoted @globalCallStack
- interpretCode execute executeString executeFile resolve canCastTo typeEqual
+ interpretCode compileCode execute executeString executeFile resolve canCastTo typeEqual
);
use Data::Dumper;
@@ -73,6 +73,40 @@ sub interpretCode {
}
}
+sub compileCode {
+ my ($code) = @_;
+
+ my $ret = "my \$i = 0; eval {\n";
+
+ foreach my $i (0 .. $#$code) {
+ my $t = $code->[$i];
+
+ if(ref($t->[1]) eq 'ARRAY' and $t->[1]->[0] eq 'func') {
+ if(not $t->[1]->[2]) {
+ # untyped function, just call, no need to go through execute
+ $ret .= "push \@globalCallStack, \$code[$i];\n";
+ $ret .= "&{\$code[$i]->[0]}(\$data, \$lscope);\n";
+ $ret .= "pop \@globalCallStack;\n";
+ } else {
+ $ret .= "\$i = $i; execute(\$code[$i], \$data, \$lscope);\n";
+ }
+ } else {
+ $ret .= "push \@\$data, \$code[$i];\n";
+ }
+ }
+
+ $ret .= <<'EOPERL';
+ };
+ if($@) {
+ print "Stack: " . Dumper($data);
+ print "Token: " . Dumper($code[$i]);
+ die;
+ }
+EOPERL
+
+ return $ret;
+}
+
sub typeStack {
my ($type) = @_;
diff --git a/interpreter/ElymasGlobal.pm b/interpreter/ElymasGlobal.pm
index 5384cb5..a93760d 100644
--- a/interpreter/ElymasGlobal.pm
+++ b/interpreter/ElymasGlobal.pm
@@ -51,23 +51,52 @@ our $global = {
die "unexpanded token in quoted code" if grep { $_->[1] eq 'tok' } @code;
- if($quoted) {
- push @$data, [sub {
- my ($data, $refScope) = @_;
- my $scope = $$refScope;
+ # if($quoted) {
+ # push @$data, [sub {
+ # my ($data, $refScope) = @_;
+ # my $scope = $$refScope;
+
+ # push @$data, [sub {
+ # my ($data) = @_;
+ # my $lscope = \{ ' parent' => $scope };
+ # interpretCode(\@code, $data, $lscope);
+ # }, ['func', 'Dumper(\@code)']];
+ # }, ['func', 'func-quoted'], \@code];
+ # } else {
+ # push @$data, [sub {
+ # my ($data) = @_;
+ # my $lscope = \{ ' parent' => $scope };
+ # interpretCode(\@code, $data, $lscope);
+ # }, ['func', 'Dumper(\@code)']];
+ # }
- push @$data, [sub {
+ if($quoted) {
+ my $sub = <<'EOPERL' .
+ sub {
+ my ($data, $refScope) = @_;
+ my $scope = $$refScope;
+ my $s = sub {
+ my ($data) = @_;
+ my $lscope = \{ ' parent' => $scope };
+EOPERL
+ compileCode(\@code) . <<'EOPERL';
+ };
+ push @$data, [$s, ['func', 'compiled sub (1)']];
+ }
+EOPERL
+ $sub = eval($sub);
+ push @$data, [$sub, ['func', 'func-quoted'], \@code];
+ } else {
+ my $sub = <<'EOPERL' .
+ sub {
my ($data) = @_;
my $lscope = \{ ' parent' => $scope };
- interpretCode(\@code, $data, $lscope);
- }, ['func', 'Dumper(\@code)']];
- }, ['func', 'func-quoted'], \@code];
- } else {
- push @$data, [sub {
- my ($data) = @_;
- my $lscope = \{ ' parent' => $scope };
- interpretCode(\@code, $data, $lscope);
- }, ['func', 'Dumper(\@code)']];
+EOPERL
+ compileCode(\@code) . <<'EOPERL';
+ };
+EOPERL
+ $sub = eval($sub);
+ push @$data, [$sub, ['func', 'compiled sub (2)']];
}
}, ['func', '}'], 'quote'],
"}'" => [sub {