module transform
import astbuilder
-import auto_super_init
import astvalidation
+import semantize
+intrude import semantize::scope
redef class ToolContext
var transform_phase: Phase = new TransformPhase(self, [typing_phase, auto_super_init_phase])
#
# Declarations are only useful for scope rules
# Once names are associated with real objects, ther declaration become useless
- # Therefore, if there is no initial value, then just detach it
+ # Therefore, if there is no initial value, then just ignore it
# Else, replace it with a simple assignment
redef fun accept_transform_visitor(v)
do
var nexpr = n_expr
if nexpr == null then
- detach
+ # do nothing
+ # note: not detached because the collection is currently under iteration
else
var nvar = v.builder.make_var_assign(self.variable.as(not null), nexpr)
replace_with(nvar)
end
end
+redef class AImpliesExpr
+ redef fun accept_transform_visitor(v)
+ do
+ # TODO
+ end
+end
+
redef class AAndExpr
# `x and y` is replaced with `if x then y else x`
redef fun accept_transform_visitor(v)
redef class AWhileExpr
redef fun accept_transform_visitor(v)
do
- # TODO
+ var nloop = v.builder.make_loop
+ var nif = v.builder.make_if(n_expr, null)
+ nloop.add nif
+
+ var nblock = n_block
+ if nblock != null then nif.n_then.add nblock
+
+ var escapemark = self.break_mark.as(not null)
+ var nbreak = v.builder.make_break(escapemark)
+ nif.n_else.add nbreak
+
+ nloop.break_mark = self.break_mark
+ nloop.continue_mark = self.continue_mark
+
+ replace_with(nloop)
end
end
redef class AForExpr
redef fun accept_transform_visitor(v)
do
- # TODO
+ var escapemark = self.break_mark
+ assert escapemark != null
+
+ var nblock = v.builder.make_block
+
+ var nexpr = n_expr
+
+ nblock.add nexpr
+
+ var iter = v.builder.make_call(nexpr.make_var_read, method_iterator.as(not null), null)
+ nblock.add iter
+
+ var nloop = v.builder.make_loop
+ nloop.break_mark = escapemark
+ nblock.add nloop
+
+ var is_ok = v.builder.make_call(iter.make_var_read, method_is_ok.as(not null), null)
+
+ var nif = v.builder.make_if(is_ok, null)
+ nloop.add nif
+
+ var nthen = nif.n_then
+ var ndo = v.builder.make_do
+ ndo.break_mark = escapemark.continue_mark
+ nthen.add ndo
+
+ if self.variables.length == 1 then
+ var item = v.builder.make_call(iter.make_var_read, method_item.as(not null), null)
+ ndo.add v.builder.make_var_assign(variables.first, item)
+ else if self.variables.length == 2 then
+ var key = v.builder.make_call(iter.make_var_read, method_key.as(not null), null)
+ ndo.add v.builder.make_var_assign(variables[0], key)
+ var item = v.builder.make_call(iter.make_var_read, method_item.as(not null), null)
+ ndo.add v.builder.make_var_assign(variables[1], item)
+ else
+ abort
+ end
+
+ ndo.add self.n_block.as(not null)
+
+ nthen.add v.builder.make_call(iter.make_var_read, method_next.as(not null), null)
+
+ var nbreak = v.builder.make_break(escapemark)
+ nif.n_else.add nbreak
+
+ var method_finish = self.method_finish
+ if method_finish != null then
+ nblock.add v.builder.make_call(iter.make_var_read, method_finish, null)
+ end
+
+ replace_with(nblock)
end
end
# t
redef fun accept_transform_visitor(v)
do
- var mtype = self.mtype.as(MClassType)
var nblock = v.builder.make_block
- var meth = v.get_method(self, "with_capacity", mtype.mclass)
- var nnew = v.builder.make_new(mtype, meth, [v.builder.make_int(n_exprs.n_exprs.length)])
+ var nnew = v.builder.make_new(with_capacity_callsite.as(not null), [v.builder.make_int(n_exprs.n_exprs.length)])
nblock.add nnew
- var madd = v.get_method(self, "push", mtype.mclass)
for nexpr in self.n_exprs.n_exprs do
- var nadd = v.builder.make_call(nnew.make_var_read, madd, [nexpr])
+ var nadd = v.builder.make_call(nnew.make_var_read, push_callsite.as(not null), [nexpr])
nblock.add nadd
end
var nres = nnew.make_var_read
end
end
-redef class ASuperstringExpr
- # `"x{y}z"` is replaced with
- #
- # var t = new Array[Object].with_capacity(3)
- # t.add("x")
- # t.add(y)
- # t.add("z")
- # t.to_s
- redef fun accept_transform_visitor(v)
- do
- var nblock = v.builder.make_block
-
- var arraytype = v.get_class(self, "Array").get_mtype([v.get_class(self, "Object").mclass_type])
- var meth = v.get_method(self, "with_capacity", arraytype.mclass)
- var nnew = v.builder.make_new(arraytype, meth, [v.builder.make_int(n_exprs.length)])
- nblock.add nnew
-
- var madd = v.get_method(self, "add", arraytype.mclass)
- for nexpr in self.n_exprs do
- var nadd = v.builder.make_call(nnew.make_var_read, madd, [nexpr])
- nblock.add nadd
- end
-
- var mtos = v.get_method(self, "to_s", arraytype.mclass)
- var ntos = v.builder.make_call(nnew.make_var_read, mtos, null)
- nblock.add ntos
-
- replace_with(nblock)
- end
-end
-
redef class ACrangeExpr
# `[x..y]` is replaced with `new Range[X](x,y)`
redef fun accept_transform_visitor(v)
do
- var mtype = self.mtype.as(MClassType)
- var meth = v.get_method(self, "init", mtype.mclass)
-
- replace_with(v.builder.make_new(mtype, meth, [n_expr, n_expr2]))
+ if parent isa AForExpr then return # to permit shortcut ranges
+ replace_with(v.builder.make_new(init_callsite.as(not null), [n_expr, n_expr2]))
end
end
# `[x..y[` is replaced with `new Range[X].without_last(x,y)`
redef fun accept_transform_visitor(v)
do
- var mtype = self.mtype.as(MClassType)
- var meth = v.get_method(self, "without_last", mtype.mclass)
-
- replace_with(v.builder.make_new(mtype, meth, [n_expr, n_expr2]))
+ if parent isa AForExpr then return # to permit shortcut ranges
+ replace_with(v.builder.make_new(init_callsite.as(not null), [n_expr, n_expr2]))
end
end
var read_args = new Array[AExpr]
var write_args = new Array[AExpr]
- for a in raw_arguments.as(not null) do
+ for a in raw_arguments do
nblock.add(a)
read_args.add(a.make_var_read)
write_args.add(a.make_var_read)
end
- var nread = v.builder.make_call(n_expr.make_var_read, callsite.mproperty, read_args)
+ var nread = v.builder.make_call(n_expr.make_var_read, callsite.as(not null), read_args)
- var nnewvalue = v.builder.make_call(nread, reassign_callsite.mproperty, [n_value])
+ var nnewvalue = v.builder.make_call(nread, reassign_callsite.as(not null), [n_value])
write_args.add(nnewvalue)
- var nwrite = v.builder.make_call(n_expr.make_var_read, write_callsite.mproperty, write_args)
+ var nwrite = v.builder.make_call(n_expr.make_var_read, write_callsite.as(not null), write_args)
nblock.add(nwrite)
replace_with(nblock)
do
var variable = self.variable.as(not null)
- var nread = v.builder.make_var_read(variable)
- var nnewvalue = v.builder.make_call(nread, reassign_callsite.mproperty, [n_value])
+ var nread = v.builder.make_var_read(variable, read_type.as(not null))
+
+ var nnewvalue = v.builder.make_call(nread, reassign_callsite.as(not null), [n_value])
var nwrite = v.builder.make_var_assign(variable, nnewvalue)
replace_with(nwrite)
var attribute = self.mproperty.as(not null)
var nread = v.builder.make_attr_read(n_expr.make_var_read, attribute)
- var nnewvalue = v.builder.make_call(nread, reassign_callsite.mproperty, [n_value])
+ var nnewvalue = v.builder.make_call(nread, reassign_callsite.as(not null), [n_value])
var nwrite = v.builder.make_attr_assign(n_expr.make_var_read, attribute, nnewvalue)
nblock.add(nwrite)