cvsuser 05/01/13 04:39:05
Modified: . MANIFEST
Added: languages/bf bfco.imc
Log:
add bfco register-only compiler
Revision Changes Path
1.821 +1 -0 parrot/MANIFEST
Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.820
retrieving revision 1.821
diff -u -r1.820 -r1.821
--- MANIFEST 13 Jan 2005 09:16:29 -0000 1.820
+++ MANIFEST 13 Jan 2005 12:39:04 -0000 1.821
@@ -2021,6 +2021,7 @@
languages/bf/bench.bf [bf]
languages/bf/bf.pasm [bf]
languages/bf/bfc.imc [bf]
+languages/bf/bfco.imc [bf]
languages/bf/countdown.bf [bf]
languages/bf/cw.bf [bf]
languages/bf/cw.txt [bf]
1.1 parrot/languages/bf/bfco.imc
Index: bfco.imc
===================================================================
# $Id: bfco.imc,v 1.1 2005/01/13 12:39:05 leo Exp $
# An Optimizing Brainfuck compiler
# By Leo based on bfc.imc by Leon
##########################
# emit register-only code
# XXX does no register range checking
# it runs the bench.bf 15 times faster then bfc.imc
##########################
.sub _main
.param pmc argv
.local int pc
.local int maxpc
.local int label
.local string labelstr
.local string code
.local string filename
.local string file
.local string line
.local string program
.local string char
program = argv[0]
# check argc
$I0 = argv
if $I0 < 2 goto usage
# Get the filename
filename = argv[1]
if filename goto SOURCE
usage:
print "usage: ../../parrot "
print program
print " file.bf\n"
end
# Read the file into S1
SOURCE:
open $P1, filename, "<"
defined $I0, $P1
if $I0, SOURCE_LOOP
print filename
print " not found\n"
branch usage
SOURCE_LOOP:
read line, $P1, 1024
file = file . line
if line goto SOURCE_LOOP
close $P1
length maxpc, file
# Initialise
code = ""
# concat code, "trace 1\n"
concat code, "new P0, .ResizableIntegerArray # memory\n"
# this array doesn't support negative indices properly
# start with some offset
concat code, "getstdout P30\n"
concat code, "pop S0, P30\n # unbuffer\n"
concat code, "getstdin P30\n"
pc = 0 # pc
label = 0 # label count
.local int depth, n_lt, n_gt, reg
concat code, " cleari\n"
# The main compiler loop
INTERP:
substr_r char, file, pc, 1
concat code, "\nSTEP"
labelstr = pc
concat code, labelstr
concat code, ": # "
concat code, char
concat code, "\n"
if char != "+" goto NOTPLUS
.local int n_plus
null n_plus
$I0 = pc + 1
plus_loop:
inc n_plus
if $I0 == maxpc goto emit_plus
substr_r char, file, $I0, 1
if char != "+" goto emit_plus
inc $I0
goto plus_loop
emit_plus:
pc = $I0 - 1
concat code, " add I"
set $S1, reg
concat code, $S1
concat code, ", "
$S0 = n_plus
concat code, $S0
concat code, "\n"
concat code, " band I"
concat code, $S1
concat code, ", 0xff\n"
goto NEXT
NOTPLUS:
if char != "-" goto NOTMINUS
.local int n_minus
null n_minus
$I0 = pc + 1
minus_loop:
inc n_minus
if $I0 == maxpc goto emit_minus
substr_r char, file, $I0, 1
if char != "-" goto emit_minus
inc $I0
goto minus_loop
emit_minus:
pc = $I0 - 1
concat code, " sub I"
set $S1, reg
concat code, $S1
concat code, ", "
$S0 = n_minus
concat code, $S0
concat code, "\n"
concat code, " band I"
concat code, $S1
concat code, ", 0xff\n"
goto NEXT
NOTMINUS:
if char != ">" goto NOTGT
null n_gt
$I0 = pc + 1
gt_loop:
inc n_gt
if $I0 == maxpc goto emit_gt
substr_r char, file, $I0, 1
if char != ">" goto emit_gt
inc $I0
goto gt_loop
emit_gt:
reg += n_gt
bsr debug
pc = $I0 - 1
goto NEXT
NOTGT:
if char != "<" goto NOTLT
null n_lt
$I0 = pc + 1
lt_loop:
inc n_lt
if $I0 == maxpc goto emit_lt
substr_r char, file, $I0, 1
if char != "<" goto emit_lt
inc $I0
goto lt_loop
emit_lt:
reg -= n_lt
bsr debug
pc = $I0 - 1
goto NEXT
NOTLT:
if char != "[" goto NOTOPEN
label = pc
depth = 0
OPEN_LOOP:
inc label
substr $S2, file, label, 1
if $S2 != "[" goto OPEN_NOTOPEN
inc depth
goto OPEN_LOOP
OPEN_NOTOPEN:
if $S2 != "]" goto OPEN_LOOP
if depth == 0 goto OPEN_NEXT
dec depth
goto OPEN_LOOP
OPEN_NEXT:
inc label
labelstr = label
concat code, " unless I"
set $S0, reg
concat code, $S0
concat code, ", STEP"
concat code, labelstr
concat code, "\n"
goto NEXT
NOTOPEN:
if char != "]" goto NOTCLOSE
label = pc
depth = 0 # "height"
CLOSE_LOOP:
dec label
substr $S2, file, label, 1
if $S2 != "]" goto CLOSE_NOTCLOSE
inc depth
goto CLOSE_LOOP
CLOSE_NOTCLOSE:
if $S2 != "[" goto CLOSE_LOOP
if depth == 0 goto CLOSE_NEXT
dec depth
goto CLOSE_LOOP
CLOSE_NEXT:
labelstr = label
concat code, " branch STEP"
concat code, labelstr
concat code, "\n"
goto NEXT
NOTCLOSE:
if char != "." goto NOTDOT
concat code, " chr S31, I"
$S0 = reg
concat code, $S0
concat code, "\n"
concat code, " print S31\n"
goto NEXT
NOTDOT:
if char != "," goto NEXT
labelstr = pc
concat code, " read S31, P30, 1\n"
concat code, " if S31, no_eof"
concat code, labelstr
concat code, "\n"
concat code, " null I31\n"
concat code, " branch eof"
concat code, labelstr
concat code, "\n"
concat code, "no_eof"
concat code, labelstr
concat code, ":\n"
concat code, " ord I31, S31\n"
concat code, "eof"
concat code, labelstr
concat code, ":\n"
$S0 = reg
concat code, " set I"
concat code, $S0
concat code, ", I31\n"
goto NEXT
NEXT:
inc pc
if pc < maxpc goto INTERP
labelstr = pc
concat code, "STEP"
concat code, labelstr
concat code, ":\n"
concat code, "end\n"
# printerr code
# printerr "\n"
# Now actually run it
compreg P1, "PASM"
compile P0, P1, code
invoke
end
debug:
ret
concat code, "# depth "
$S0 = depth
concat code, $S0
concat code, " reg "
$S0 = reg
concat code, $S0
concat code, "\n"
ret
.end