class
compiler::CheckParamDefs
sys::Obj
compiler::CompilerSupport
compiler::CompilerStep
compiler::CheckParamDefs
1 //
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 20 Jun 06 Brian Frank Creation
7 // 1 Oct 06 Brian Frank Port from Java to Fan
8 //
9
10 **
11 ** CheckParamDefs is used to process all the parameter default
12 ** expressions for all the methods. What we are looking for is
13 ** default expressions which use default expressions before it
14 ** which require us to insert a store instruction.
15 **
16 class CheckParamDefs : CompilerStep
17 {
18
19 new make(Compiler compiler)
20 : super(compiler)
21 {
22 }
23
24 override Void run()
25 {
26 walk(types, VisitDepth.slotDef)
27 }
28
29 override Void visitMethodDef(MethodDef m)
30 {
31 // unless there are two or more defaults don't bother
32 params := m.paramDefs
33 num := params.size
34 if (num <= 1 || params[-2].def == null)
35 return
36
37 // if a def expr calculates a local used after it,
38 // then we need to insert a store (local set)
39 (num-1).times |Int i|
40 {
41 if (params[i].def == null) return
42 if (usedInSuccDef(params, i))
43 {
44 param := params[i]
45 var := m.vars[i]
46 loc := param.location
47
48 if (!param.name.equals(var.name)) throw err("invalid state", loc)
49
50 param.def = BinaryExpr.makeAssign(LocalVarExpr.make(loc, var), param.def, true)
51 }
52 }
53 }
54
55 Bool usedInSuccDef(ParamDef[] params, Int index)
56 {
57 this.name = params[index].name
58 for (i:=index+1; i<params.size; ++i)
59 {
60 this.used = false
61 params[i].def.walk(this)
62 if (this.used) return true
63 }
64 return false
65 }
66
67 override Expr visitExpr(Expr expr)
68 {
69 if (expr.id === ExprId.localVar)
70 {
71 local := (LocalVarExpr)expr
72 if (name == local.var.name) used = true
73 }
74 return expr
75 }
76
77 Str name
78 Bool used
79
80 }
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 20 Jun 06 Brian Frank Creation
7 // 1 Oct 06 Brian Frank Port from Java to Fan
8 //
9
10 **
11 ** CheckParamDefs is used to process all the parameter default
12 ** expressions for all the methods. What we are looking for is
13 ** default expressions which use default expressions before it
14 ** which require us to insert a store instruction.
15 **
16 class CheckParamDefs : CompilerStep
17 {
18
19 new make(Compiler compiler)
20 : super(compiler)
21 {
22 }
23
24 override Void run()
25 {
26 walk(types, VisitDepth.slotDef)
27 }
28
29 override Void visitMethodDef(MethodDef m)
30 {
31 // unless there are two or more defaults don't bother
32 params := m.paramDefs
33 num := params.size
34 if (num <= 1 || params[-2].def == null)
35 return
36
37 // if a def expr calculates a local used after it,
38 // then we need to insert a store (local set)
39 (num-1).times |Int i|
40 {
41 if (params[i].def == null) return
42 if (usedInSuccDef(params, i))
43 {
44 param := params[i]
45 var := m.vars[i]
46 loc := param.location
47
48 if (!param.name.equals(var.name)) throw err("invalid state", loc)
49
50 param.def = BinaryExpr.makeAssign(LocalVarExpr.make(loc, var), param.def, true)
51 }
52 }
53 }
54
55 Bool usedInSuccDef(ParamDef[] params, Int index)
56 {
57 this.name = params[index].name
58 for (i:=index+1; i<params.size; ++i)
59 {
60 this.used = false
61 params[i].def.walk(this)
62 if (this.used) return true
63 }
64 return false
65 }
66
67 override Expr visitExpr(Expr expr)
68 {
69 if (expr.id === ExprId.localVar)
70 {
71 local := (LocalVarExpr)expr
72 if (name == local.var.name) used = true
73 }
74 return expr
75 }
76
77 Str name
78 Bool used
79
80 }