Author: allison
Date: Thu Apr 27 14:11:06 2006
New Revision: 12451
Added:
trunk/languages/punie/lib/Node.pir
trunk/languages/punie/t/node.t (contents, props changed)
Removed:
trunk/languages/punie/lib/PAST/Node.pir
trunk/languages/punie/lib/POST/Node.pir
trunk/languages/punie/t/past_node.t
trunk/languages/punie/t/post_node.t
Modified:
trunk/ (props changed)
trunk/MANIFEST
trunk/languages/punie/lib/PAST.pir
trunk/languages/punie/lib/PAST/Code.pir
trunk/languages/punie/lib/PAST/Exp.pir
trunk/languages/punie/lib/PAST/Op.pir
trunk/languages/punie/lib/PAST/Stmt.pir
trunk/languages/punie/lib/PAST/Stmts.pir
trunk/languages/punie/lib/PAST/Sub.pir
trunk/languages/punie/lib/PAST/Val.pir
trunk/languages/punie/lib/PAST/Var.pir
trunk/languages/punie/lib/POST.pir
trunk/languages/punie/lib/POST/Label.pir
trunk/languages/punie/lib/POST/Op.pir
trunk/languages/punie/lib/POST/Ops.pir
trunk/languages/punie/lib/POST/Sub.pir
trunk/languages/punie/lib/POST/Val.pir
trunk/languages/punie/lib/POST/Var.pir
trunk/languages/punie/t/post_var.t
Log:
Punie: refactoring all node types to a single base class.
Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST (original)
+++ trunk/MANIFEST Thu Apr 27 14:11:06 2006
@@ -1124,6 +1124,7 @@
languages/punie/punie.pir [punie]
languages/punie/overview.pod [punie]
languages/punie/README [punie]
+languages/punie/lib/Node.pir [punie]
languages/punie/lib/PAST.pir [punie]
languages/punie/lib/past2post.tg [punie]
languages/punie/lib/punie.pg [punie]
@@ -1137,14 +1138,12 @@
languages/punie/lib/PIRGrammar.pir [punie]
languages/punie/lib/PAST/Code.pir [punie]
languages/punie/lib/PAST/Exp.pir [punie]
-languages/punie/lib/PAST/Node.pir [punie]
languages/punie/lib/PAST/Op.pir [punie]
languages/punie/lib/PAST/Stmt.pir [punie]
languages/punie/lib/PAST/Stmts.pir [punie]
languages/punie/lib/PAST/Sub.pir [punie]
languages/punie/lib/PAST/Val.pir [punie]
languages/punie/lib/PAST/Var.pir [punie]
-languages/punie/lib/POST/Node.pir [punie]
languages/punie/lib/POST/Op.pir [punie]
languages/punie/lib/POST/Sub.pir [punie]
languages/punie/lib/POST/Val.pir [punie]
@@ -1158,13 +1157,12 @@
languages/punie/t/base_term.t [punie]
languages/punie/t/harness [punie]
languages/punie/t/io_print.t [punie]
+languages/punie/t/node.t [punie]
languages/punie/t/op_goto.t [punie]
languages/punie/t/past.t [punie]
-languages/punie/t/past_node.t [punie]
languages/punie/t/past_op.t [punie]
languages/punie/t/past_val.t [punie]
languages/punie/t/post.t [punie]
-languages/punie/t/post_node.t [punie]
languages/punie/t/post_op.t [punie]
languages/punie/t/post_val.t [punie]
languages/punie/t/post_var.t [punie]
Added: trunk/languages/punie/lib/Node.pir
==============================================================================
--- (empty file)
+++ trunk/languages/punie/lib/Node.pir Thu Apr 27 14:11:06 2006
@@ -0,0 +1,132 @@
+=head1 NAME
+
+Node - a base class for syntax tree nodes
+
+=head1 DESCRIPTION
+
+All PAST and POST nodes subclass from this base type.
+
+=cut
+
+.namespace [ "Node" ]
+
+.sub "__onload" :load
+ .local pmc base
+ newclass base, "Node"
+ addattribute base, "source" # the original source code
+ addattribute base, "pos" # offset position in source
+ addattribute base, "children" # child nodes
+ .return ()
+.end
+
+
+.sub __init :method
+ $P1 = new .Undef
+ $P2 = new .Integer
+ $P3 = new .Undef
+
+ setattribute self, "source", $P1
+ setattribute self, "pos", $P2
+ setattribute self, "children", $P3
+.end
+
+.sub "set_node" :method
+ .param string source
+ .param int pos
+ .param pmc children
+ $P1 = getattribute self, "source"
+ $P1 = source
+ $P2 = getattribute self, "pos"
+ $P2 = pos
+ setattribute self, "children", children
+ .return ()
+.end
+
+.sub source :method
+ $P2 = getattribute self, "source"
+ .return ($P2)
+.end
+
+.sub pos :method
+ $P2 = getattribute self, "pos"
+ .return ($P2)
+.end
+
+.sub children :method
+ $P2 = getattribute self, "children"
+ .return ($P2)
+.end
+
+.sub "dump" :method
+ .param int level :optional
+ .local string indent
+ indent = repeat " ", level # tab is 4 spaces here
+ level += 1 # set level for attributes
+ $S0 = typeof self
+ print indent
+ print "<"
+ print $S0
+ print "> => { \n"
+
+ # print source for this node
+ self.dump_attribute("source", level)
+ self.dump_attribute("pos", level)
+ self.dump_children(level)
+
+ # close off current node display
+ print indent
+ print "}\n"
+ .return ()
+.end
+
+.sub "dump_attribute" :method
+ .param string name
+ .param int level :optional
+ .local string indent
+ indent = repeat " ", level # tab is 4 spaces here
+ # print value for this attribute
+ print indent
+ print "'"
+ print name
+ print "' => "
+ $P1 = getattribute self, name
+ $I0 = defined $P1
+ unless $I0 goto attribute_undef
+ print "'"
+ print $P1
+ print "'"
+ goto attribute_def
+ attribute_undef:
+ print "undef"
+ attribute_def:
+ print ",\n"
+ .return ()
+.end
+
+.sub "dump_children" :method
+ .param int level :optional
+ .local string indent
+ indent = repeat " ", level # tab is 4 spaces here
+ level += 1 # set level to pass on to children
+ # print children for this node
+ print indent
+ print "'children' => ["
+ $P3 = getattribute self, "children"
+ $I0 = defined $P3
+ unless $I0 goto no_children
+ print "\n"
+ .local pmc iter
+ iter = new Iterator, $P3 # loop over the array
+ iter = 0 # start at the beginning
+ loop_start:
+ unless iter goto loop_end
+ $P1 = shift iter
+ $P1.dump(level)
+ goto loop_start
+ loop_end:
+ print indent
+
+ no_children:
+ print "]\n"
+ .return ()
+.end
Modified: trunk/languages/punie/lib/PAST.pir
==============================================================================
--- trunk/languages/punie/lib/PAST.pir (original)
+++ trunk/languages/punie/lib/PAST.pir Thu Apr 27 14:11:06 2006
@@ -7,15 +7,15 @@
The Punie compiler progresses through two levels of syntax tree. PAST
(Parrot/Punie Abstract Syntax Tree) is a high-level tree, which closely
corresponds to the semantics of the language (though in a desugared
-form). PAST::Node implements the abstract syntax tree nodes created by
-the Punie compiler.
+form). The individual subclasses of Node implement the abstract syntax
+tree nodes created by the Punie compiler.
=cut
.namespace [ "PAST" ]
.sub "__onload" :load
- load_bytecode "languages/punie/lib/PAST/Node.pir"
+ load_bytecode "languages/punie/lib/Node.pir"
load_bytecode "languages/punie/lib/PAST/Code.pir"
load_bytecode "languages/punie/lib/PAST/Exp.pir"
load_bytecode "languages/punie/lib/PAST/Op.pir"
Modified: trunk/languages/punie/lib/PAST/Code.pir
==============================================================================
--- trunk/languages/punie/lib/PAST/Code.pir (original)
+++ trunk/languages/punie/lib/PAST/Code.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
PAST::Code represents a block of code in the AST. It is a subclass of
-PAST::Node.
+Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'PAST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'PAST::Code'
.return ()
.end
Modified: trunk/languages/punie/lib/PAST/Exp.pir
==============================================================================
--- trunk/languages/punie/lib/PAST/Exp.pir (original)
+++ trunk/languages/punie/lib/PAST/Exp.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
PAST::Exp is an expression in the AST. It is a subclass of
-PAST::Node.
+Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'PAST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'PAST::Exp'
.return ()
.end
Modified: trunk/languages/punie/lib/PAST/Op.pir
==============================================================================
--- trunk/languages/punie/lib/PAST/Op.pir (original)
+++ trunk/languages/punie/lib/PAST/Op.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
PAST::Op is a function call (or operation or method call) in the AST. It
-is a subclass of PAST::Node.
+is a subclass of Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'PAST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'PAST::Op'
addattribute base, "op" # the operator name
.return ()
Modified: trunk/languages/punie/lib/PAST/Stmt.pir
==============================================================================
--- trunk/languages/punie/lib/PAST/Stmt.pir (original)
+++ trunk/languages/punie/lib/PAST/Stmt.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
PAST::Stmt is an individual statement in the AST. It is a subclass of
-PAST::Node.
+Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'PAST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'PAST::Stmt'
.return ()
.end
Modified: trunk/languages/punie/lib/PAST/Stmts.pir
==============================================================================
--- trunk/languages/punie/lib/PAST/Stmts.pir (original)
+++ trunk/languages/punie/lib/PAST/Stmts.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
PAST::Stmts is the top-level of the AST and contains a series of
-statements. It is a subclass of PAST::Node.
+statements. It is a subclass of Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'PAST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'PAST::Stmts'
.return ()
.end
Modified: trunk/languages/punie/lib/PAST/Sub.pir
==============================================================================
--- trunk/languages/punie/lib/PAST/Sub.pir (original)
+++ trunk/languages/punie/lib/PAST/Sub.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
PAST::Sub is a subroutine declaration in the AST. It is a subclass of
-PAST::Node.
+Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'PAST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'PAST::Sub'
.return ()
.end
Modified: trunk/languages/punie/lib/PAST/Val.pir
==============================================================================
--- trunk/languages/punie/lib/PAST/Val.pir (original)
+++ trunk/languages/punie/lib/PAST/Val.pir Thu Apr 27 14:11:06 2006
@@ -4,7 +4,7 @@
=head1 DESCRIPTION
-PAST::Val is a subclass of PAST::Node.
+PAST::Val is a subclass of Node.
=cut
@@ -12,7 +12,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'PAST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'PAST::Val'
addattribute base, "value" # the value of this leaf
addattribute base, "valtype" # the value type of this leaf
Modified: trunk/languages/punie/lib/PAST/Var.pir
==============================================================================
--- trunk/languages/punie/lib/PAST/Var.pir (original)
+++ trunk/languages/punie/lib/PAST/Var.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
PAST::Var is a node containing a variable in the AST. It is a subclass
-of PAST::Node.
+of Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'PAST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'PAST::Var'
.return ()
.end
Modified: trunk/languages/punie/lib/POST.pir
==============================================================================
--- trunk/languages/punie/lib/POST.pir (original)
+++ trunk/languages/punie/lib/POST.pir Thu Apr 27 14:11:06 2006
@@ -6,7 +6,7 @@
The Punie compiler progresses through two levels of syntax tree. POST
(Parrot/Punie Opcode Syntax Tree) is a low-level tree, which closely
-corresponds to the semantics of PIR/PASM. POST::Node is the base class
+corresponds to the semantics of PIR/PASM. Node is the base class
for the opcode syntax tree nodes created by the Punie compiler.
=cut
@@ -14,7 +14,7 @@
.namespace [ "POST" ]
.sub "__onload" :load
- load_bytecode "languages/punie/lib/POST/Node.pir"
+ load_bytecode "languages/punie/lib/Node.pir"
load_bytecode "languages/punie/lib/POST/Op.pir"
load_bytecode "languages/punie/lib/POST/Ops.pir"
load_bytecode "languages/punie/lib/POST/Sub.pir"
Modified: trunk/languages/punie/lib/POST/Label.pir
==============================================================================
--- trunk/languages/punie/lib/POST/Label.pir (original)
+++ trunk/languages/punie/lib/POST/Label.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
POST::Label is a node containing a label in the OST. It is a subclass of
-POST::Node. Labels can either be a destination or an argument for an
+Node. Labels can either be a destination or an argument for an
opcode.
=cut
@@ -14,7 +14,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'POST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'POST::Label'
addattribute base, "name" # the PIR name of this label
addattribute base, "dest" # whether label is a destination
@@ -40,19 +40,6 @@
.return ()
.end
-.sub new_dummy :method
- .param string name :optional
- .param int got_name :opt_flag
- # First we create a temporary variable
- if got_name goto with_name
- $S1 = self.generate_label()
- goto endif
- with_name:
- $S1 = self.generate_label(name)
- endif:
- self.'name'($S1)
- .return ()
-.end
.sub name :method
.param string name :optional
@@ -118,3 +105,41 @@
print "}\n"
.return ()
.end
+
+.sub generate_label :method
+ .param string name :optional
+ .param int got_name :opt_flag
+ .local string label
+ unless got_name goto no_name
+ label = name . "_"
+ no_name:
+ label .= "label_"
+ $I1 = _new_label_id()
+ $S1 = $I1
+ label .= $S1
+ .return (label)
+.end
+
+# Autoincrementing id generator
+.sub _new_label_id
+ .local int id
+ id = 0
+loop:
+ inc id
+ .yield(id)
+ goto loop
+.end
+
+.sub new_dummy :method
+ .param string name :optional
+ .param int got_name :opt_flag
+ # First we create a temporary variable
+ if got_name goto with_name
+ $S1 = self.generate_label()
+ goto endif
+ with_name:
+ $S1 = self.generate_label(name)
+ endif:
+ self.'name'($S1)
+ .return ()
+.end
Modified: trunk/languages/punie/lib/POST/Op.pir
==============================================================================
--- trunk/languages/punie/lib/POST/Op.pir (original)
+++ trunk/languages/punie/lib/POST/Op.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
POST::Op is a call to an opcode in the OST. It is a subclass of
-POST::Node.
+Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'POST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'POST::Op'
addattribute base, "op" # the operator name
.return ()
Modified: trunk/languages/punie/lib/POST/Ops.pir
==============================================================================
--- trunk/languages/punie/lib/POST/Ops.pir (original)
+++ trunk/languages/punie/lib/POST/Ops.pir Thu Apr 27 14:11:06 2006
@@ -7,7 +7,7 @@
POST::Ops is the top-level of the AST and contains a sequence of
opcodes. (Ultimately these are flattened out, but they're a convenient
fiction when a single HLL statement generates a sequence of opcodes.)
-POST::Ops is a subclass of POST::Node.
+POST::Ops is a subclass of Node.
=cut
@@ -15,7 +15,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'POST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'POST::Ops'
addattribute base, "tmpvar" # temp variable for result of ops
.return ()
Modified: trunk/languages/punie/lib/POST/Sub.pir
==============================================================================
--- trunk/languages/punie/lib/POST/Sub.pir (original)
+++ trunk/languages/punie/lib/POST/Sub.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
POST::Sub is a subroutine declaration in the OST. It is a subclass of
-POST::Node.
+Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'POST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'POST::Sub'
.return ()
.end
Modified: trunk/languages/punie/lib/POST/Val.pir
==============================================================================
--- trunk/languages/punie/lib/POST/Val.pir (original)
+++ trunk/languages/punie/lib/POST/Val.pir Thu Apr 27 14:11:06 2006
@@ -4,7 +4,7 @@
=head1 DESCRIPTION
-POST::Val is a literal value in the OST. It is a subclass of POST::Node.
+POST::Val is a literal value in the OST. It is a subclass of Node.
=cut
@@ -12,7 +12,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'POST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'POST::Val'
addattribute base, "value" # the value of this leaf
addattribute base, "valtype" # the value type of this leaf
Modified: trunk/languages/punie/lib/POST/Var.pir
==============================================================================
--- trunk/languages/punie/lib/POST/Var.pir (original)
+++ trunk/languages/punie/lib/POST/Var.pir Thu Apr 27 14:11:06 2006
@@ -5,7 +5,7 @@
=head1 DESCRIPTION
POST::Var is a node containing a variable in the OST. It is a subclass
-of POST::Node.
+of Node.
=cut
@@ -13,7 +13,7 @@
.sub "__onload" :load
.local pmc base
- $P0 = getclass 'POST::Node'
+ $P0 = getclass 'Node'
base = subclass $P0, 'POST::Var'
addattribute base, "varname" # the PIR name of this variable
.return ()
@@ -37,6 +37,25 @@
.return ()
.end
+.sub generate_temp :method
+ .local string temp
+ temp = "$P"
+ $I1 = _new_temp_id()
+ $S1 = $I1
+ temp .= $S1
+ .return (temp)
+.end
+
+# Autoincrementing id generator
+.sub _new_temp_id
+ .local int id
+ id = 0
+loop:
+ inc id
+ .yield(id)
+ goto loop
+.end
+
.sub new_temp :method
$S1 = self.generate_temp()
self.varname($S1)
Added: trunk/languages/punie/t/node.t
==============================================================================
--- (empty file)
+++ trunk/languages/punie/t/node.t Thu Apr 27 14:11:06 2006
@@ -0,0 +1,108 @@
+#!/usr/bin/perl
+
+use strict;
+use lib qw(t . lib ../lib ../../lib ../../../lib);
+use Parrot::Test tests => 5;
+
+pir_output_is(<<'CODE', <<'OUT', 'load the library');
+.sub _main
+ load_bytecode 'languages/punie/lib/Node.pir'
+.end
+CODE
+OUT
+
+pir_output_is(<<'CODE', <<'OUT', 'construct a node');
+.sub _main
+ load_bytecode 'languages/punie/lib/Node.pir'
+ .local pmc node
+ node = new 'Node'
+ .return()
+.end
+CODE
+OUT
+
+pir_output_is(<<'CODE', <<'OUT', 'set attributes manually');
+.sub _main
+ load_bytecode 'languages/punie/lib/Node.pir'
+ .local pmc node
+ node = new 'Node'
+ $P0 = getattribute node, 'source'
+ $P0 = "foo\n"
+ $P1 = getattribute node, 'source'
+ print $P1
+ $P0 = getattribute node, 'pos'
+ $P0 = 42
+ $P1 = getattribute node, 'pos'
+ print $P1
+ print "\n"
+ $P1 = new .String
+ $P1 = "bar\n"
+ $P2 = new .ResizablePMCArray
+ push $P2, $P1
+ setattribute node, 'children', $P2
+ $P2 = getattribute node, 'children'
+ $P3 = $P2[0]
+ print $P3
+ .return ()
+.end
+CODE
+foo
+42
+bar
+OUT
+
+pir_output_is(<<'CODE', <<'OUT', 'set attributes via method');
+.sub _main
+ load_bytecode 'languages/punie/lib/Node.pir'
+ .local pmc node
+ node = new 'Node'
+ $P0 = new .String
+ $P0 = 'bar'
+ $P1 = new .ResizablePMCArray
+ push $P1, $P0
+ node.set_node('foo', 42, $P1)
+ $P1 = getattribute node, 'source'
+ print $P1
+ print "\n"
+ $P1 = getattribute node, 'pos'
+ print $P1
+ print "\n"
+ $P2 = getattribute node, 'children'
+ $P3 = $P2[0]
+ print $P3
+ print "\n"
+ .return ()
+.end
+CODE
+foo
+42
+bar
+OUT
+
+pir_output_is(<<'CODE', <<'OUT', 'dump node structure in visual format');
+.sub _main
+ load_bytecode 'languages/punie/lib/Node.pir'
+ .local pmc node1
+ .local pmc node2
+ node1 = new 'Node'
+ node2 = new 'Node'
+ node2.set_node('b', 9, $P0)
+ $P1 = new .ResizablePMCArray
+ push $P1, node2
+ node1.set_node('foo', 42, $P1)
+ node1.dump()
+ .return ()
+.end
+CODE
+<Node> => {
+ 'source' => 'foo',
+ 'pos' => '42',
+ 'children' => [
+ <Node> => {
+ 'source' => 'b',
+ 'pos' => '9',
+ 'children' => []
+ }
+ ]
+}
+OUT
Modified: trunk/languages/punie/t/post_var.t
==============================================================================
--- trunk/languages/punie/t/post_var.t (original)
+++ trunk/languages/punie/t/post_var.t Thu Apr 27 14:11:06 2006
@@ -2,7 +2,7 @@
use strict;
use lib qw(t . lib ../lib ../../lib ../../../lib);
-use Parrot::Test tests => 2;
+use Parrot::Test tests => 3;
pir_output_is(<<'CODE', <<'OUT', 'set attributes via method');
.sub _main
@@ -43,3 +43,21 @@
'varname' => 'bar',
}
OUT
+
+pir_output_is(<<'CODE', <<'OUT', 'generate a temporary variable');
+.sub _main
+ load_bytecode 'languages/punie/lib/POST.pir'
+ .local pmc node
+ node = new 'POST::Var'
+ $S1 = node.generate_temp()
+ print $S1
+ print "\n"
+ $S2 = node.generate_temp()
+ print $S2
+ print "\n"
+ .return()
+.end
+CODE
+$P1
+$P2
+OUT