Dan/All --

> Keen! And I added a little_languages subdir to hold compilers of this sort. 
> (And checked in jako while I was at it...)

Thanks! I've enhanced the compiler a bit and fixed a bug in the
handling of while(){}. I've also added some features and rewritten
the fibo.pasm example program as fibo.jako.

I'm attaching jako.diff and fibo.jako, and also the compiler output
fibo.pasm. Until my CVS write access is turned on, I'll need someone
else to apply the compiler patch and check in fibo.jako.

The new compiler also handles if(){}, but I'm not certain it does so
correctly.

Also, the current assembler doesn't do a few opcode qualifier
inferences that I think it should (noted with TODOs in the compiler
code).

Anyway, there's more to come...


Regards,

-- Gregor
 _____________________________________________________________________ 
/     perl -e 'srand(-2091643526); print chr rand 90 for (0..4)'      \

   Gregor N. Purdy                          [EMAIL PROTECTED]
   Focus Research, Inc.                http://www.focusresearch.com/
   8080 Beckett Center Drive #203                   513-860-3570 vox
   West Chester, OH 45069                           513-860-3579 fax
\_____________________________________________________________________/
Index: little_languages/jako_compiler.pl
===================================================================
RCS file: /home/perlcvs/parrot/little_languages/jako_compiler.pl,v
retrieving revision 1.1
diff -u -r1.1 jako_compiler.pl
--- little_languages/jako_compiler.pl   2001/09/14 14:58:51     1.1
+++ little_languages/jako_compiler.pl   2001/09/14 16:13:48
@@ -158,26 +158,38 @@
 
 
 #
-# begin_while()
+# begin_while_block()
 #
-# TODO: Support more than just register-to-register '==' and '!='.
-#
 
-sub begin_while
+sub begin_while_block
 {
   my ($cond) = @_;
 
   $block_count++;
-  my $prefix = "L_$block_count";
-  push @block_stack, { NEXT => $line, PREFIX => $prefix };
+  my $prefix = "_W$block_count";
+  push @block_stack, { TYPE => 'while', NEXT => $line, PREFIX => $prefix };
+
+  #
+  # TODO: Note that the assembler wasn't inferring the opcode qualifiers, so we had
+  # to code them explicitly. We should remove the qualifiers as soon as the
+  # assembler is fixed.
+  #
 
   if ($cond =~ m/^(.*)\s*==\s*(.*)$/) {
     my @args = map_args($1, $2);
-    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "eq", "$args[0], $args[1], 
${prefix}_REDO, ${prefix}_LAST";
+    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "eq_i_ic", "$args[0], $args[1], 
+${prefix}_REDO, ${prefix}_LAST";
     printf "%s_REDO:\n", $prefix;
   } elsif ($cond =~ m/^(.*)\s*!=\s*(.*)$/) {
+    my @args = map_args($1, $2);
+    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "ne_i_ic", "$args[0], $args[1], 
+${prefix}_REDO, ${prefix}_LAST";
+    printf "%s_REDO:\n", $prefix;
+  } elsif ($cond =~ m/^(.*)\s*<=\s*(.*)$/) {
+    my @args = map_args($1, $2);
+    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "le_i_ic", "$args[0], $args[1], 
+${prefix}_REDO, ${prefix}_LAST";
+    printf "%s_REDO:\n", $prefix;
+  } elsif ($cond =~ m/^(.*)\s*>=\s*(.*)$/) {
     my @args = map_args($1, $2);
-    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "ne", "$args[0], $args[1], 
${prefix}_REDO, ${prefix}_LAST";
+    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "ge_i_ic", "$args[0], $args[1], 
+${prefix}_REDO, ${prefix}_LAST";
     printf "%s_REDO:\n", $prefix;
   } else {
     printf(STDERR "jako: Syntax error. Unrecognized condition in while on line 
%d.\n", $line);
@@ -186,25 +198,167 @@
 
 
 #
-# end_while()
+# begin_if_block()
 #
 
-sub end_while
+sub begin_if_block
 {
-  my $prefix = "L_$block_count";
+  my ($cond) = @_;
+
+  $block_count++;
+  my $prefix = "_I$block_count";
+  push @block_stack, { TYPE => 'if', NEXT => $line, PREFIX => $prefix };
 
+  #
+  # TODO: Note that the assembler wasn't inferring the opcode qualifiers, so we had
+  # to code them explicitly. We should remove the qualifiers as soon as the
+  # assembler is fixed.
+  #
+
+  if ($cond =~ m/^(.*)\s*==\s*(.*)$/) {
+    my @args = map_args($1, $2);
+    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "eq_i_ic", "$args[0], $args[1], 
+${prefix}_REDO, ${prefix}_LAST";
+    printf "%s_REDO:\n", $prefix;
+  } elsif ($cond =~ m/^(.*)\s*!=\s*(.*)$/) {
+    my @args = map_args($1, $2);
+    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "ne_i_ic", "$args[0], $args[1], 
+${prefix}_REDO, ${prefix}_LAST";
+    printf "%s_REDO:\n", $prefix;
+  } elsif ($cond =~ m/^(.*)\s*<=\s*(.*)$/) {
+    my @args = map_args($1, $2);
+    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "le_i_ic", "$args[0], $args[1], 
+${prefix}_REDO, ${prefix}_LAST";
+    printf "%s_REDO:\n", $prefix;
+  } elsif ($cond =~ m/^(.*)\s*>=\s*(.*)$/) {
+    my @args = map_args($1, $2);
+    printf "%-12s %-8s %s\n", "${prefix}_NEXT:", "ge_i_ic", "$args[0], $args[1], 
+${prefix}_REDO, ${prefix}_LAST";
+    printf "%s_REDO:\n", $prefix;
+  } else {
+    printf(STDERR "jako: Syntax error. Unrecognized condition in while on line 
+%d.\n", $line);
+  }
+}
+
+
+#
+# end_block()
+#
+
+sub end_block
+{
   unless (@block_stack) {
     printf(STDERR "jako: Syntax error. Closing brace without open block on line 
%d.\n", $line);
     return;
   }
 
-  pop @block_stack;
+  my $block  = pop @block_stack;
+  my $prefix = $block->{PREFIX};
 
+  #
+  # TODO: Note that the assembler wasn't inferring the opcode qualifiers, so we had
+  # to code them explicitly. We should remove the qualifiers as soon as the
+  # assembler is fixed.
+  #
+
+  if ($block->{TYPE} eq 'while') {
+    printf("%-12s %-8s %s\n", '', 'branch_ic', "${prefix}_NEXT", );
+    # TODO: Is there a better unconditional jump (branch_ic)?
+  }
+
   printf "%s_LAST:\n", $prefix;
 }
 
 
 #
+# do_next()
+#
+
+sub do_next
+{
+  #
+  # TODO: Note that the assembler wasn't inferring the opcode qualifiers, so we had
+  # to code them explicitly. We should remove the qualifiers as soon as the
+  # assembler is fixed.
+  #
+
+  foreach (reverse @block_stack) {
+    if ($_->{TYPE} eq 'while') {
+      my $prefix = $_->{PREFIX};
+      printf("%-12s %-8s %s\n", '', 'branch_ic', "${prefix}_NEXT", );
+      last;
+    }
+  }
+}
+
+
+#
+# do_last()
+#
+
+sub do_last
+{
+  #
+  # TODO: Note that the assembler wasn't inferring the opcode qualifiers, so we had
+  # to code them explicitly. We should remove the qualifiers as soon as the
+  # assembler is fixed.
+  #
+
+  foreach (reverse @block_stack) {
+    if ($_->{TYPE} eq 'while') {
+      my $prefix = $_->{PREFIX};
+      printf("%-12s %-8s %s\n", '', 'branch_ic', "${prefix}_LAST", );
+      # TODO: Is there a better unconditional jump (branch_ic)?
+      last;
+    }
+  }
+}
+
+
+#
+# do_redo()
+#
+
+sub do_redo
+{
+  #
+  # TODO: Note that the assembler wasn't inferring the opcode qualifiers, so we had
+  # to code them explicitly. We should remove the qualifiers as soon as the
+  # assembler is fixed.
+  #
+
+  foreach (reverse @block_stack) {
+    if ($_->{TYPE} eq 'while') {
+      my $prefix = $_->{PREFIX};
+      printf("%-12s %-8s %s\n", '', 'branch_ic', "${prefix}_REDO", );
+      # TODO: Is there a better unconditional jump (branch_ic)?
+      last;
+    }
+  }
+}
+
+
+#
+# do_add()
+#
+
+sub do_add
+{
+  my ($dest, $a, $b) = @_;
+
+  printf("%-12s %-8s %s\n", '', 'add', join(", ", map_args($dest, $a, $b)));
+}
+
+
+#
+# do_inc()
+#
+
+sub do_inc
+{
+  my ($dest, $amount) = @_;
+
+  printf("%-12s %-8s %s\n", '', 'inc', join(", ", map_args($dest, 1)));
+}
+
+
+#
 # parse_args()
 #
 
@@ -290,12 +444,42 @@
   }
 
   if (m/^while\s*\(\s*(.*)\s*\)\s*{$/) {
-    begin_while($1);
+    begin_while_block($1);
+    next;
+  }
+
+  if (m/^if\s*\(\s*(.*)\s*\)\s*{$/) {
+    begin_if_block($1);
     next;
   }
 
   if (m/^}$/) {
-    end_while();
+    end_block();
+    next;
+  }
+
+  if (m/^next$/) {
+    do_next();
+    next;
+  }
+
+  if (m/^last$/) {
+    do_last();
+    next;
+  }
+
+  if (m/^redo$/) {
+    do_redo();
+    next;
+  }
+
+  if 
+(m/([A-Za-z][A-Za-z0-9]*)\s*=\s*([A-Za-z][A-Za-z0-9_]*)\s*[+]\s*([A-Za-z][A-Za-z0-9_]*)/)
+ {
+    do_add($1, $2, $3);
+    next;
+  }
+
+  if (m/([A-Za-z][A-Za-z0-9_]*)\s*[+][+]$/) {
+    do_inc($1, 1);
     next;
   }
 
@@ -304,7 +488,7 @@
     next;
   }
 
-  print "jako: Syntax error on line $line: '$_'.\n";
+  print STDERR "jako: Syntax error on line $line: '$_'.\n";
 }
 
 exit 0;
#
# fibo.jako
#
# Adapted from fibo.pasm by [EMAIL PROTECTED]
#
# Copyright (C) 2001 Gregor N. Purdy. All rights reserved.
# This program is free software. It is subject to the same
# license as Perl itself.
#

n is int;
i is int;

a is int;
b is int;
f is int;

n = 24;

print("Algorithm F (Fibonacci's function)\n");
print("  Calculating fib(");
print(n);
print(") = ...\n");

a = 1;
b = 1;
f = 1;

i = 3;
while (i <= n) {
  f = a + b;
  a = b;
  b = f;
  i++;
}

print("  ... = ");
print(f);
print("\n");

end;

# This file produced by the Jako Compiler
#
# fibo.jako
#
# Adapted from fibo.pasm by [EMAIL PROTECTED]
#
# Copyright (C) 2001 Gregor N. Purdy. All rights reserved.
# This program is free software. It is subject to the same
# license as Perl itself.
#
# n: I1
# i: I2
# a: I3
# b: I4
# f: I5
             set      I1, 24
             print    "Algorithm F (Fibonacci's function)\n"
             print    "  Calculating fib("
             print    I1
             print    ") = ...\n"
             set      I3, 1
             set      I4, 1
             set      I5, 1
             set      I2, 3
_W1_NEXT:    le_i_ic  I2, I1, _W1_REDO, _W1_LAST
_W1_REDO:
             add      I5, I3, I4
             set      I3, I4
             set      I4, I5
             inc      I2, 1
             branch_ic _W1_NEXT
_W1_LAST:
             print    "  ... = "
             print    I5
             print    "\n"
             end     

Reply via email to