Skip to content

Instantly share code, notes, and snippets.

Created June 10, 2011 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/1019984 to your computer and use it in GitHub Desktop.
Save anonymous/1019984 to your computer and use it in GitHub Desktop.
diff --git a/src/NQP/Actions.pm b/src/NQP/Actions.pm
index a982234..d6d4afd 100644
--- a/src/NQP/Actions.pm
+++ b/src/NQP/Actions.pm
@@ -54,7 +54,7 @@ class NQP::Actions is HLL::Actions {
# compilation unit that is using this one will then replace it
# with its view later (or be in a position to restore it).
$unit.loadinit().push(PAST::Op.new(
- :pasttype('bind'),
+ :pasttype('bind_6model'),
PAST::Var.new( :name('GLOBAL'), :namespace([]), :scope('package') ),
$*SC.get_slot_past_for_object($*PACKAGE)
));
@@ -326,7 +326,7 @@ class NQP::Actions is HLL::Actions {
}
unless $block.arity {
$block.unshift(
- PAST::Op.new( :pasttype('bind'),
+ PAST::Op.new( :pasttype('bind_6model'),
PAST::Var.new( :scope('lexical'), :name('$!'), :isdecl(1) ),
PAST::Var.new( :scope('lexical'), :name('$_')),
),
@@ -345,7 +345,7 @@ class NQP::Actions is HLL::Actions {
$block,
PAST::Var.new( :scope('register'), :name('exception')),
),
- PAST::Op.new( :pasttype('bind'),
+ PAST::Op.new( :pasttype('bind_6model'),
PAST::Var.new( :scope('keyed'),
PAST::Var.new( :scope('register'), :name('exception')),
'handled'
@@ -371,7 +371,7 @@ class NQP::Actions is HLL::Actions {
$past.handlers([PAST::Control.new(
:handle_types_except('CONTROL'),
PAST::Stmts.new(
- PAST::Op.new( :pasttype('bind'),
+ PAST::Op.new( :pasttype('bind_6model'),
PAST::Var.new( :scope('keyed'),
PAST::Var.new( :scope('register'), :name('exception')),
'handled'
@@ -778,7 +778,7 @@ class NQP::Actions is HLL::Actions {
# it per invocation.
$*SC.install_package_routine($*PACKAGE, $name, $past);
@BLOCK[0][0].push(PAST::Op.new(
- :pasttype('bind'),
+ :pasttype('bind_6model'),
lexical_package_lookup([$name], $/),
PAST::Var.new( :name($name), :scope('lexical') )
));
@@ -1543,7 +1543,7 @@ class NQP::RegexActions is Regex::P6Regex::Actions {
:name('MATCH'),
:pasttype('callmethod')
),
- :pasttype('bind')
+ :pasttype('bind_6model')
),
$block
);
diff --git a/src/NQP/Grammar.pm b/src/NQP/Grammar.pm
index f70da68..41a9099 100644
--- a/src/NQP/Grammar.pm
+++ b/src/NQP/Grammar.pm
@@ -704,8 +704,8 @@ grammar NQP::Grammar is HLL::Grammar {
token infix:sym<=> {
<sym> <.panic: 'Assignment ("=") not supported in NQP, use ":=" instead'>
}
- token infix:sym<:=> { <sym> <O('%assignment, :pasttype<bind>')> }
- token infix:sym<::=> { <sym> <O('%assignment, :pasttype<bind>')> }
+ token infix:sym<:=> { <sym> <O('%assignment, :pasttype<bind_6model>')> }
+ token infix:sym<::=> { <sym> <O('%assignment, :pasttype<bind_6model>')> }
token infix:sym<,> { <sym> <O('%comma, :pasttype<list>')> }
diff --git a/src/NQP/SymbolTable.pm b/src/NQP/SymbolTable.pm
index a3c5754..7fd6dfc 100644
--- a/src/NQP/SymbolTable.pm
+++ b/src/NQP/SymbolTable.pm
@@ -79,7 +79,7 @@ class NQP::SymbolTable is HLL::Compiler::SerializationContextBuilder {
$path := PAST::Op.new(:pirop('nqp_get_package_through_who PPs'), $path, ~$_);
}
self.add_event(:deserialize_past(PAST::Op.new(
- :pasttype('bind'),
+ :pasttype('bind_6model'),
PAST::Var.new(
:scope('keyed'),
PAST::Op.new( :pirop('get_who PP'), $path ),
@@ -125,7 +125,7 @@ class NQP::SymbolTable is HLL::Compiler::SerializationContextBuilder {
# specified name.
method install_package_routine($package, $name, $past_block) {
my $fixup := PAST::Op.new(
- :pasttype('bind'),
+ :pasttype('bind_6model'),
PAST::Var.new(
:scope('keyed'),
PAST::Op.new( :pirop('get_who PP'), self.get_slot_past_for_object($package) ),
@@ -416,7 +416,7 @@ class NQP::SymbolTable is HLL::Compiler::SerializationContextBuilder {
PAST::Op.new( :pirop('get_class Ps'), 'NQPLexPad' )
),
PAST::Op.new(
- :pasttype('bind'),
+ :pasttype('bind_6model'),
PAST::Var.new( :name('cur_sc'), :scope('register'), :isdecl(1) ),
PAST::Op.new( :pirop('nqp_create_sc Ps'), self.handle() )
),
diff --git a/src/PAST/SixModelPASTExtensions.pir b/src/PAST/SixModelPASTExtensions.pir
index 67f1a22..61434c5 100644
--- a/src/PAST/SixModelPASTExtensions.pir
+++ b/src/PAST/SixModelPASTExtensions.pir
@@ -36,47 +36,50 @@ some PAST that will produce it or a name that it can be looked up by.
.const int STORAGE_SPEC_BP_NUM = 2
.const int STORAGE_SPEC_BP_STR = 3
-.sub 'attribute_6model' :method :multi(_, ['PAST';'Var'])
+.sub 'attribute_6model_type' :method
.param pmc node
- .param pmc bindpost
- .local pmc ops
- $P0 = get_hll_global ['POST'], 'Ops'
- ops = $P0.'new'('node'=>node)
- .local string name
- name = node.'name'()
- name = self.'escape'(name)
-
# See if we have a type. If so, use it to determine what op to use
# and what the register type will be.
.local pmc type
- .local string get_attr_op, set_attr_op, coerce_reg_type
.local int primitive_type_id
type = node.'type'()
primitive_type_id = repr_get_primitive_type_spec type
if primitive_type_id == STORAGE_SPEC_BP_INT goto prim_int
if primitive_type_id == STORAGE_SPEC_BP_NUM goto prim_num
if primitive_type_id == STORAGE_SPEC_BP_STR goto prim_str
- get_attr_op = 'getattribute'
- set_attr_op = 'setattribute'
- coerce_reg_type = 'P'
- goto type_done
+ .return ('P', 'getattribute', 'setattribute')
prim_int:
- get_attr_op = 'repr_get_attr_int'
- set_attr_op = 'repr_bind_attr_int'
- coerce_reg_type = 'I'
- goto type_done
+ .return ('i', 'repr_get_attr_int', 'repr_bind_attr_int')
prim_num:
- get_attr_op = 'repr_get_attr_num'
- set_attr_op = 'repr_bind_attr_num'
- coerce_reg_type = 'N'
- goto type_done
+ .return ('n', 'repr_get_attr_num', 'repr_bind_attr_num')
prim_str:
- get_attr_op = 'repr_get_attr_str'
- set_attr_op = 'repr_bind_attr_str'
- coerce_reg_type = 'S'
- goto type_done
- type_done:
+ .return ('s', 'repr_get_attr_str', 'repr_bind_attr_str')
+.end
+
+
+
+.sub 'attribute_6model' :method :multi(_, ['PAST';'Var'])
+ .param pmc node
+ .param pmc bindpost
+
+ .local pmc ops
+ $P0 = get_hll_global ['POST'], 'Ops'
+ ops = $P0.'new'('node'=>node)
+
+ unless bindpost goto have_bindpost
+ $S0 = bindpost.'result'()
+ bindpost = $P0.'new'('result'=>$S0)
+ have_bindpost:
+
+ .local string name
+ name = node.'name'()
+ name = self.'escape'(name)
+
+ # See if we have a type. If so, use it to determine what op to use
+ # and what the register type will be.
+ .local string get_attr_op, set_attr_op, coerce_reg_type
+ (coerce_reg_type, get_attr_op, set_attr_op) = self.'attribute_6model_type'(node)
# We have three cases here.
# 0 children = use self
@@ -113,11 +116,8 @@ some PAST that will produce it or a name that it can be looked up by.
.tailcall self.'vivify'(node, ops, fetchop, storeop)
attribute_bind:
- if coerce_reg_type == 'P' goto attribute_bind_coerced
- $P0 = self.'uniquereg'(coerce_reg_type)
- ops.'push_pirop'('set', $P0, bindpost)
- bindpost = $P0
- attribute_bind_coerced:
+ bindpost = self.'coerce'(bindpost, coerce_reg_type)
+ ops.'push'(bindpost)
ops.'push_pirop'(set_attr_op, call_on, name, bindpost)
ops.'result'(bindpost)
.return (ops)
@@ -144,12 +144,42 @@ some PAST that will produce it or a name that it can be looked up by.
.tailcall self.'vivify'(node, ops, fetchop, storeop)
attribute_bind_handle:
- if coerce_reg_type == 'P' goto attribute_bind_handle_coerced
- $P0 = self.'uniquereg'(coerce_reg_type)
- ops.'push_pirop'('set', $P0, bindpost)
- bindpost = $P0
- attribute_bind_handle_coerced:
+ bindpost = self.'coerce'(bindpost, coerce_reg_type)
+ ops.'push'(bindpost)
ops.'push_pirop'(set_attr_op, call_on, handle, name, bindpost)
ops.'result'(bindpost)
.return (ops)
.end
+
+
+.sub 'bind_6model' :method :multi(_, ['PAST';'Op'])
+ .param pmc node
+ .param pmc options :slurpy :named
+
+ .local pmc ops, lpast, rpast, lpost, rpost
+ lpast = node[0]
+ rpast = node[1]
+
+ .local string rtype
+ rtype = 'P'
+ $I0 = isa lpast, ['PAST';'Var']
+ unless $I0 goto have_rtype
+ $S0 = lpast.'scope'()
+ unless $S0 == 'attribute_6model' goto have_rtype
+ (rtype) = self.'attribute_6model_type'(lpast)
+ have_rtype:
+
+ $P0 = get_hll_global ['POST'], 'Ops'
+ ops = $P0.'new'('node'=>node)
+ rpost = self.'as_post'(rpast, 'rtype'=>rtype)
+ rpost = self.'coerce'(rpost, rtype)
+ ops.'push'(rpost)
+
+ lpast.'lvalue'(1)
+ lpost = self.'as_post'(lpast, 'bindpost'=>rpost)
+ ops.'push'(lpost)
+ ops.'result'(lpost)
+ .return (ops)
+.end
+
+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment