@@ -54,7 +54,9 @@ type compiler struct {
54
54
locals map [string ]int
55
55
constantsPool map [interface {}]int
56
56
intConstantsPool map [int ]int
57
- params map [string ]int
57
+
58
+ params map [string ]int
59
+ intParams map [string ]int
58
60
59
61
code []byte
60
62
constants []interface {}
@@ -89,20 +91,31 @@ func (cl *compiler) compileFunc(fn *ast.FuncDecl) *Func {
89
91
panic (cl .errorUnsupportedType (fn .Name , cl .retType , "function result" ))
90
92
}
91
93
92
- dbg := funcDebugInfo {
93
- paramNames : make ([]string , cl .fnType .Params ().Len ()),
94
- }
95
-
96
94
cl .params = make (map [string ]int , cl .fnType .Params ().Len ())
95
+ cl .intParams = make (map [string ]int , cl .fnType .Params ().Len ())
97
96
for i := 0 ; i < cl .fnType .Params ().Len (); i ++ {
98
97
p := cl .fnType .Params ().At (i )
99
98
paramName := p .Name ()
100
99
paramType := p .Type ()
101
- cl .params [paramName ] = i
102
- dbg .paramNames [i ] = paramName
103
100
if ! cl .isSupportedType (paramType ) {
104
101
panic (cl .errorUnsupportedType (fn .Name , paramType , paramName + " param" ))
105
102
}
103
+ if typeIsInt (paramType ) {
104
+ cl .intParams [paramName ] = len (cl .intParams )
105
+ } else {
106
+ cl .params [paramName ] = len (cl .params )
107
+ }
108
+ }
109
+
110
+ dbg := funcDebugInfo {
111
+ paramNames : make ([]string , len (cl .params )),
112
+ intParamNames : make ([]string , len (cl .intParams )),
113
+ }
114
+ for paramName , i := range cl .params {
115
+ dbg .paramNames [i ] = paramName
116
+ }
117
+ for paramName , i := range cl .intParams {
118
+ dbg .intParamNames [i ] = paramName
106
119
}
107
120
108
121
cl .compileStmt (fn .Body )
@@ -298,10 +311,20 @@ func (cl *compiler) compileAssignStmt(assign *ast.AssignStmt) {
298
311
}
299
312
}
300
313
314
+ func (cl * compiler ) isParamName (varname string ) bool {
315
+ if _ , ok := cl .params [varname ]; ok {
316
+ return true
317
+ }
318
+ if _ , ok := cl .intParams [varname ]; ok {
319
+ return true
320
+ }
321
+ return false
322
+ }
323
+
301
324
func (cl * compiler ) getLocal (v ast.Expr , varname string ) int {
302
325
id , ok := cl .locals [varname ]
303
326
if ! ok {
304
- if _ , ok := cl .params [ varname ]; ok {
327
+ if cl .isParamName ( varname ) {
305
328
panic (cl .errorf (v , "can't assign to %s, params are readonly" , varname ))
306
329
}
307
330
panic (cl .errorf (v , "%s is not a writeable local variable" , varname ))
@@ -645,7 +668,11 @@ func (cl *compiler) compileIdent(ident *ast.Ident) {
645
668
return
646
669
}
647
670
if paramIndex , ok := cl .params [ident .String ()]; ok {
648
- cl .emit8 (pickOp (typeIsInt (tv .Type ), opPushIntParam , opPushParam ), paramIndex )
671
+ cl .emit8 (opPushParam , paramIndex )
672
+ return
673
+ }
674
+ if paramIndex , ok := cl .intParams [ident .String ()]; ok {
675
+ cl .emit8 (opPushIntParam , paramIndex )
649
676
return
650
677
}
651
678
if localIndex , ok := cl .locals [ident .String ()]; ok {
0 commit comments