M cmd/snowc/main.go => cmd/snowc/main.go +2 -2
@@ 210,7 210,7 @@ func (c *cmd) Typecheck(stdio *mainer.Stdio, args []string) error {
}
func (c *cmd) Codegen(stdio *mainer.Stdio, args []string) error {
- files, err := codegen.GenerateFiles(c.GenDir, args...)
+ files, err := codegen.Exec(c.GenDir, args...)
for _, file := range files {
fmt.Fprintf(stdio.Stdout, "> %s\n", file)
}
@@ 247,7 247,7 @@ func (c *cmd) splitDashDash(args []string) (parts [2][]string) {
}
func (c *cmd) build(stdio *mainer.Stdio, paths []string, goflags []string) error {
- files, err := codegen.GenerateFiles(c.GenDir, paths...)
+ files, err := codegen.Exec(c.GenDir, paths...)
if err != nil {
var el scanner.ErrorList
if errors.As(err, &el) {
M pkg/codegen/mangle.go => pkg/codegen/mangle.go +44 -42
@@ 33,57 33,59 @@ func mangle(unit *semantic.Unit) *nameResolver {
ruses[decl] = true
}
+ // TODO: I believe it should be based by walking the scopes instead! Would
+ // work for all declarations (all registered in scopes), and even for Self
+ // (which has no AST/ASG node).
+
names := make(map[semantic.Decl]string)
- semantic.Inspect(unit, func(n semantic.Node) bool {
- // first, process the generic cases for all decls
- if decl, ok := n.(semantic.Decl); ok {
- // Universe types are handled by the translator.goTypeExprFor method.
+ InspectScope(unit.Scope(), func(s *semantic.Scope) bool {
+ if s == nil {
+ return false
+ }
- // if this is the main function, mangle it as "main" and that's it.
+ for _, decl := range s.Symbols {
+ // first, process the generic cases for all decls
if decl == unit.Main {
names[decl] = basicIdentsToGo[decl.Ident()]
- return true
- }
- }
-
- switch n := n.(type) {
- case *semantic.Fn:
- var b fmtBuilder
- if n.Scope().IsTopLevel() || n.MethodOf != nil {
- b.withExport(false)
+ continue
}
- names[n] = b.get(n.Ident())
-
- case *semantic.Var:
- // if this is a variable (not a struct field nor a function parameter)
- // and its value is unused, mangle as "_".
- if !ruses[n] && n.ParamOf == nil && n.PropOf == nil {
- // TODO: unless public/exported
- names[n] = "_"
- break
+ if decl.Scope().IsUniverse() {
+ if _, ok := decl.Type().(*semantic.BasicType); ok {
+ names[decl] = basicIdentsToGo[decl.Ident()]
+ continue
+ }
}
- var b fmtBuilder
- if n.Scope().IsTopLevel() || n.PropOf != nil {
- b.withExport(false)
- }
- names[n] = b.get(n.Ident())
+ switch decl := decl.(type) {
+ case *semantic.Fn:
+ var b fmtBuilder
+ if decl.Scope().IsTopLevel() || decl.MethodOf != nil {
+ b.withExport(false)
+ }
+ names[decl] = b.get(decl.Ident())
+
+ case *semantic.Var:
+ // if this is a variable (not a struct field nor a function parameter)
+ // and its value is unused, mangle as "_".
+ if !ruses[decl] && decl.ParamOf == nil && decl.PropOf == nil {
+ // TODO: unless public/exported
+ names[decl] = "_"
+ break
+ }
- case *semantic.Struct:
- var b fmtBuilder
- b.withExport(false)
- if !n.Scope().IsTopLevel() {
- b.withScope(n.Scope())
- }
- names[n] = b.get(n.Ident())
-
- case *semantic.Ident:
- // if the referenced declaration is in the Universe and the type is
- // BasicType, mangle as its corresponding Go basic type or identifier.
- if ref := n.Ref; ref != nil && ref.Scope().IsUniverse() {
- if _, ok := ref.Type().(*semantic.BasicType); ok {
- names[ref] = basicIdentsToGo[ref.Ident()]
+ var b fmtBuilder
+ if decl.Scope().IsTopLevel() || decl.PropOf != nil {
+ b.withExport(false)
+ }
+ names[decl] = b.get(decl.Ident())
+
+ case *semantic.Struct:
+ var b fmtBuilder
+ b.withExport(false)
+ if !decl.Scope().IsTopLevel() {
+ b.withScope(decl.Scope())
}
+ names[decl] = b.get(decl.Ident())
}
}
return true
M pkg/codegen/testdata/fn_nested_struct_method.snow.want => pkg/codegen/testdata/fn_nested_struct_method.snow.want +33 -19
@@ 2,39 2,53 @@ package main
import "fmt"
-type _ɤU_0_0ɤS struct {
- _ɤx string
+type _ا4اS struct {
+ _اx string
+}
+
+func _ا4اSاnew(
+ s _ا4اS,
+) _ا4اS {
+ var r _ا4اS
+ return r
}
func (
- self *_ɤU_0_0ɤS,
-) _ɤinit() {
- self._ɤx = "hello"
+ self *_ا4اS,
+) _اinit() {
+ self._اx = "hello"
}
-type _ɤU_0_0_0ɤT struct {
- _ɤy string
+type _ا5اT struct {
+ _اy string
+}
+
+func _ا5اTاnew(
+ s _ا5اT,
+) _ا5اT {
+ var r _ا5اT
+ return r
}
func (
- self *_ɤU_0_0_0ɤT,
-) _ɤappend(
+ self *_ا5اT,
+) _اappend(
s string,
) {
- self._ɤy = self._ɤy + s
+ self._اy = self._اy + s
}
func main() {
- var s _ɤU_0_0ɤS
- var t _ɤU_0_0_0ɤT
- s._ɤinit()
- t._ɤappend(s._ɤx)
- t._ɤappend(", world")
- _ɤprintln(t._ɤy)
+ var s _ا4اS
+ var t _ا5اT
+ s._اinit()
+ t._اappend(s._اx)
+ t._اappend(", world")
+ _اprintln(t._اy)
}
-func _ɤprintln(
- _0 string,
+func _اprintln(
+ s string,
) {
- fmt.Println(_0)
+ fmt.Println(s)
}
M pkg/codegen/testdata/fn_struct_method.snow.want => pkg/codegen/testdata/fn_struct_method.snow.want +0 -2
@@ 22,14 22,12 @@ func _ا5اSاnew(
func (
self *_ا5اS,
) _اinc() {
- var _ _ا5اS
self._اx = self._اx + 1
}
func (
self *_ا5اS,
) _اrefinc() {
- var self _ا5اS
self._اx = self._اx + 1
}
A pkg/codegen/visit_scopes.go => pkg/codegen/visit_scopes.go +34 -0
@@ 0,0 1,34 @@
+package codegen
+
+import "git.sr.ht/~mna/snow/pkg/semantic"
+
+type ScopeVisitor interface {
+ VisitScope(s *semantic.Scope) (w ScopeVisitor)
+}
+
+func WalkScope(v ScopeVisitor, s *semantic.Scope) {
+ if v = v.VisitScope(s); v == nil {
+ return
+ }
+ for _, child := range s.Children {
+ WalkScope(v, child)
+ }
+ v.VisitScope(nil)
+}
+
+type inspector func(s *semantic.Scope) bool
+
+func (f inspector) VisitScope(s *semantic.Scope) ScopeVisitor {
+ if f(s) {
+ return f
+ }
+ return nil
+}
+
+// InspectScope traverses the scopes in breadth-first order: It starts by calling
+// f(s); s must not be nil. If f returns true, Inspect invokes f
+// recursively for each of the non-nil children of s, followed by a
+// call of f(nil).
+func InspectScope(s *semantic.Scope, f func(*semantic.Scope) bool) {
+ WalkScope(inspector(f), s)
+}
M pkg/semantic/scope.go => pkg/semantic/scope.go +0 -3
@@ 147,9 147,6 @@ func (s *Scope) Register(ident string, decl Decl) bool {
if _, ok := s.Symbols[ident]; ok {
return false
}
- if s.Symbols == nil {
- s.Symbols = make(map[string]Decl)
- }
s.Symbols[ident] = decl
return true
}
M pkg/semantic/testdata/check/fn_access_var_outside_struct.snow.want => pkg/semantic/testdata/check/fn_access_var_outside_struct.snow.want +2 -6
@@ 8,16 8,12 @@ file testdata/fn_access_var_outside_struct.snow [0, 1, 0]
ident string [type: string]
fn get [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
ident x [var: int]
struct T [0, 1, 0] [type: struct T]
fn get [let: () -> string]
ident string [type: string]
- block [2]
- let: self [let: struct T]
- ident T [type: struct T]
+ block [1]
return
ident y [var: string]
M pkg/semantic/testdata/check/fn_assign_struct_fields.snow.want => pkg/semantic/testdata/check/fn_assign_struct_fields.snow.want +1 -3
@@ 41,6 41,4 @@ file testdata/fn_assign_struct_fields.snow [0, 1, 1]
var: y [var: int]
ident int [type: int]
fn z [let: () -> void]
- block [1]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [0]
M pkg/semantic/testdata/check/fn_assign_struct_method_to_var.snow.want => pkg/semantic/testdata/check/fn_assign_struct_method_to_var.snow.want +2 -6
@@ 33,17 33,13 @@ file testdata/fn_assign_struct_method_to_var.snow [0, 1, 1]
ident int [type: int]
fn get [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
ident x [var: int]
ref fn set [let: (int) -> void]
let: v [let: int]
ident int [type: int]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
assign
ident x [var: int]
ident v [let: int]
M pkg/semantic/testdata/check/fn_call_struct_method.snow.want => pkg/semantic/testdata/check/fn_call_struct_method.snow.want +1 -3
@@ 15,9 15,7 @@ file testdata/fn_call_struct_method.snow [0, 1, 1]
fn add [let: (int) -> void]
let: y [let: int]
ident int [type: int]
- block [2]
- let: self [let: struct Point]
- ident Point [type: struct Point]
+ block [1]
assign
ident x [var: int]
binary [+] [value: int]
M pkg/semantic/testdata/check/fn_call_with_labels.snow.want => pkg/semantic/testdata/check/fn_call_with_labels.snow.want +1 -3
@@ 49,6 49,4 @@ file testdata/fn_call_with_labels.snow [0, 2, 1]
fn do [let: (int) -> void]
let: z [let: int]
ident int [type: int]
- block [1]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [0]
M pkg/semantic/testdata/check/fn_complex_selectors.snow.want => pkg/semantic/testdata/check/fn_complex_selectors.snow.want +1 -3
@@ 49,9 49,7 @@ file testdata/fn_complex_selectors.snow [0, 2, 1]
ident int [type: int]
sig [0->1] [type: () -> int]
ident int [type: int]
- block [3]
- let: self [let: struct T]
- ident T [type: struct T]
+ block [2]
fn func [let: () -> int]
ident int [type: int]
block [1]
M pkg/semantic/testdata/check/fn_invalid_ref_call.snow.want => pkg/semantic/testdata/check/fn_invalid_ref_call.snow.want +1 -3
@@ 7,9 7,7 @@ file testdata/fn_invalid_ref_call.snow [0, 1, 0]
ref fn set [let: (int) -> void]
let: v [let: int]
ident int [type: int]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
assign
ident x [var: int]
ident v [let: int]
M pkg/semantic/testdata/check/fn_invalid_ref_call_via_value.snow.want => pkg/semantic/testdata/check/fn_invalid_ref_call_via_value.snow.want +1 -3
@@ 7,9 7,7 @@ file testdata/fn_invalid_ref_call_via_value.snow [0, 1, 0]
ref fn set [let: (int) -> void]
let: v [let: int]
ident int [type: int]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
assign
ident x [var: int]
ident v [let: int]
M pkg/semantic/testdata/check/fn_method_explicit_self.snow.want => pkg/semantic/testdata/check/fn_method_explicit_self.snow.want +1 -3
@@ 13,9 13,7 @@ file testdata/fn_method_explicit_self.snow [0, 1, 1]
ident int [type: int]
fn getX [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
select [let: int]
ident self [let: struct S]
M pkg/semantic/testdata/check/fn_nested_struct_method.snow.want => pkg/semantic/testdata/check/fn_nested_struct_method.snow.want +2 -6
@@ 5,9 5,7 @@ file testdata/fn_nested_struct_method.snow [0, 1, 0]
var: x [var: string]
ident string [type: string]
ref fn init [let: () -> void]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
assign
ident x [var: string]
string ["hello"] [const: string]
@@ 17,9 15,7 @@ file testdata/fn_nested_struct_method.snow [0, 1, 0]
ref fn append [let: (string) -> void]
let: s [let: string]
ident string [type: string]
- block [2]
- var: self [var: struct T]
- ident T [type: struct T]
+ block [1]
assign
ident y [var: string]
binary [+] [value: string]
M pkg/semantic/testdata/check/fn_nested_struct_self.snow.want => pkg/semantic/testdata/check/fn_nested_struct_self.snow.want +1 -3
@@ 7,9 7,7 @@ file testdata/fn_nested_struct_self.snow [0, 0, 1]
ident int [type: int]
fn negate [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct T]
- ident T [type: struct T]
+ block [1]
return
unary [-] [value: int]
select [let: int]
M pkg/semantic/testdata/check/fn_ref_on_fn_nested_in_method.snow.want => pkg/semantic/testdata/check/fn_ref_on_fn_nested_in_method.snow.want +1 -3
@@ 3,8 3,6 @@ file testdata/fn_ref_on_fn_nested_in_method.snow [0, 0, 1]
var: x [var: int]
ident int [type: int]
ref fn rf [let: () -> void]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
ref fn non_method [let: () -> void]
block [0]
M pkg/semantic/testdata/check/fn_return_struct.snow.want => pkg/semantic/testdata/check/fn_return_struct.snow.want +1 -3
@@ 48,6 48,4 @@ file testdata/fn_return_struct.snow [0, 2, 1]
var: y [var: int]
ident int [type: int]
fn z [let: () -> void]
- block [1]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [0]
M pkg/semantic/testdata/check/fn_struct_main_method.snow.want => pkg/semantic/testdata/check/fn_struct_main_method.snow.want +1 -3
@@ 5,6 5,4 @@ file testdata/fn_struct_main_method.snow [0, 1, 1]
fn main [let: (int) -> void]
let: x [let: int]
ident int [type: int]
- block [1]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [0]
M pkg/semantic/testdata/check/fn_struct_method_access_top_level.snow.want => pkg/semantic/testdata/check/fn_struct_method_access_top_level.snow.want +1 -3
@@ 6,8 6,6 @@ file testdata/fn_struct_method_access_top_level.snow [1, 1, 1]
struct S [0, 1, 0] [type: struct S]
fn get [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
ident x [var: int]
M pkg/semantic/testdata/check/fn_struct_order_independent.snow.want => pkg/semantic/testdata/check/fn_struct_order_independent.snow.want +1 -3
@@ 6,9 6,7 @@ file testdata/fn_struct_order_independent.snow [0, 0, 1]
ident int [type: int]
fn test [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
binary [+] [value: int]
ident x [var: int]
M pkg/semantic/testdata/check/fn_struct_self_shadow.snow.want => pkg/semantic/testdata/check/fn_struct_self_shadow.snow.want +1 -3
@@ 4,9 4,7 @@ file testdata/fn_struct_self_shadow.snow [0, 0, 1]
ident int [type: int]
fn get [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
select [let: int]
ident self [let: struct S]
M pkg/semantic/testdata/check/fn_struct_self_uses.snow.want => pkg/semantic/testdata/check/fn_struct_self_uses.snow.want +1 -3
@@ 1,8 1,6 @@
file testdata/fn_struct_self_uses.snow [0, 0, 1]
struct S [0, 1, 0] [type: struct S]
fn set [let: () -> void]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
var: self [var: int]
ident int [type: int]
M pkg/semantic/testdata/check/struct_var_expr_call_method.snow.want => pkg/semantic/testdata/check/struct_var_expr_call_method.snow.want +2 -6
@@ 12,9 12,7 @@ file testdata/struct_var_expr_call_method.snow [0, 1, 1]
ident y [let: int]
fn f [let: () -> int]
ident int [type: int]
- block [3]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [2]
assign
ident x [var: int]
binary [+] [value: int]
@@ 24,9 22,7 @@ file testdata/struct_var_expr_call_method.snow [0, 1, 1]
ident x [var: int]
ref fn f2 [let: () -> int]
ident int [type: int]
- block [5]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [4]
assign
ident x [var: int]
binary [+] [value: int]
M pkg/semantic/testdata/types/fn_access_var_outside_struct.snow.want => pkg/semantic/testdata/types/fn_access_var_outside_struct.snow.want +2 -6
@@ 8,16 8,12 @@ file testdata/fn_access_var_outside_struct.snow [0, 1, 0]
ident string [type: string]
fn get [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
ident x [var: int]
struct T [0, 1, 0] [type: struct T]
fn get [let: () -> string]
ident string [type: string]
- block [2]
- let: self [let: struct T]
- ident T [type: struct T]
+ block [1]
return
ident y [var: string]
M pkg/semantic/testdata/types/fn_assign_struct_fields.snow.want => pkg/semantic/testdata/types/fn_assign_struct_fields.snow.want +1 -3
@@ 41,6 41,4 @@ file testdata/fn_assign_struct_fields.snow [0, 1, 1]
var: y [var: int]
ident int [type: int]
fn z [let: () -> void]
- block [1]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [0]
M pkg/semantic/testdata/types/fn_assign_struct_method_to_var.snow.want => pkg/semantic/testdata/types/fn_assign_struct_method_to_var.snow.want +2 -6
@@ 33,17 33,13 @@ file testdata/fn_assign_struct_method_to_var.snow [0, 1, 1]
ident int [type: int]
fn get [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
ident x [var: int]
ref fn set [let: (int) -> void]
let: v [let: int]
ident int [type: int]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
assign
ident x [var: int]
ident v [let: int]
M pkg/semantic/testdata/types/fn_call_struct_method.snow.want => pkg/semantic/testdata/types/fn_call_struct_method.snow.want +1 -3
@@ 15,9 15,7 @@ file testdata/fn_call_struct_method.snow [0, 1, 1]
fn add [let: (int) -> void]
let: y [let: int]
ident int [type: int]
- block [2]
- let: self [let: struct Point]
- ident Point [type: struct Point]
+ block [1]
assign
ident x [var: int]
binary [+] [value: int]
M pkg/semantic/testdata/types/fn_call_with_labels.snow.want => pkg/semantic/testdata/types/fn_call_with_labels.snow.want +1 -3
@@ 49,6 49,4 @@ file testdata/fn_call_with_labels.snow [0, 2, 1]
fn do [let: (int) -> void]
let: z [let: int]
ident int [type: int]
- block [1]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [0]
M pkg/semantic/testdata/types/fn_complex_selectors.snow.want => pkg/semantic/testdata/types/fn_complex_selectors.snow.want +1 -3
@@ 49,9 49,7 @@ file testdata/fn_complex_selectors.snow [0, 2, 1]
ident int [type: int]
sig [0->1] [type: () -> int]
ident int [type: int]
- block [3]
- let: self [let: struct T]
- ident T [type: struct T]
+ block [2]
fn func [let: () -> int]
ident int [type: int]
block [1]
M pkg/semantic/testdata/types/fn_invalid_ref_call.snow.want => pkg/semantic/testdata/types/fn_invalid_ref_call.snow.want +1 -3
@@ 7,9 7,7 @@ file testdata/fn_invalid_ref_call.snow [0, 1, 0]
ref fn set [let: (int) -> void]
let: v [let: int]
ident int [type: int]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
assign
ident x [var: int]
ident v [let: int]
M pkg/semantic/testdata/types/fn_invalid_ref_call_via_value.snow.want => pkg/semantic/testdata/types/fn_invalid_ref_call_via_value.snow.want +1 -3
@@ 7,9 7,7 @@ file testdata/fn_invalid_ref_call_via_value.snow [0, 1, 0]
ref fn set [let: (int) -> void]
let: v [let: int]
ident int [type: int]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
assign
ident x [var: int]
ident v [let: int]
M pkg/semantic/testdata/types/fn_method_explicit_self.snow.want => pkg/semantic/testdata/types/fn_method_explicit_self.snow.want +1 -3
@@ 13,9 13,7 @@ file testdata/fn_method_explicit_self.snow [0, 1, 1]
ident int [type: int]
fn getX [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
select [let: int]
ident self [let: struct S]
M pkg/semantic/testdata/types/fn_nested_struct_method.snow.want => pkg/semantic/testdata/types/fn_nested_struct_method.snow.want +2 -6
@@ 5,9 5,7 @@ file testdata/fn_nested_struct_method.snow [0, 1, 0]
var: x [var: string]
ident string [type: string]
ref fn init [let: () -> void]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
assign
ident x [var: string]
string ["hello"] [const: string]
@@ 17,9 15,7 @@ file testdata/fn_nested_struct_method.snow [0, 1, 0]
ref fn append [let: (string) -> void]
let: s [let: string]
ident string [type: string]
- block [2]
- var: self [var: struct T]
- ident T [type: struct T]
+ block [1]
assign
ident y [var: string]
binary [+] [value: string]
M pkg/semantic/testdata/types/fn_nested_struct_self.snow.want => pkg/semantic/testdata/types/fn_nested_struct_self.snow.want +1 -3
@@ 7,9 7,7 @@ file testdata/fn_nested_struct_self.snow [0, 0, 1]
ident int [type: int]
fn negate [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct T]
- ident T [type: struct T]
+ block [1]
return
unary [-] [value: int]
select [let: int]
M pkg/semantic/testdata/types/fn_ref_on_fn_nested_in_method.snow.want => pkg/semantic/testdata/types/fn_ref_on_fn_nested_in_method.snow.want +1 -3
@@ 3,8 3,6 @@ file testdata/fn_ref_on_fn_nested_in_method.snow [0, 0, 1]
var: x [var: int]
ident int [type: int]
ref fn rf [let: () -> void]
- block [2]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [1]
ref fn non_method [let: () -> void]
block [0]
M pkg/semantic/testdata/types/fn_return_struct.snow.want => pkg/semantic/testdata/types/fn_return_struct.snow.want +1 -3
@@ 48,6 48,4 @@ file testdata/fn_return_struct.snow [0, 2, 1]
var: y [var: int]
ident int [type: int]
fn z [let: () -> void]
- block [1]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [0]
M pkg/semantic/testdata/types/fn_struct_main_method.snow.want => pkg/semantic/testdata/types/fn_struct_main_method.snow.want +1 -3
@@ 5,6 5,4 @@ file testdata/fn_struct_main_method.snow [0, 1, 1]
fn main [let: (int) -> void]
let: x [let: int]
ident int [type: int]
- block [1]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [0]
M pkg/semantic/testdata/types/fn_struct_method_access_top_level.snow.want => pkg/semantic/testdata/types/fn_struct_method_access_top_level.snow.want +1 -3
@@ 6,8 6,6 @@ file testdata/fn_struct_method_access_top_level.snow [1, 1, 1]
struct S [0, 1, 0] [type: struct S]
fn get [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
ident x [var: int]
M pkg/semantic/testdata/types/fn_struct_order_independent.snow.want => pkg/semantic/testdata/types/fn_struct_order_independent.snow.want +1 -3
@@ 6,9 6,7 @@ file testdata/fn_struct_order_independent.snow [0, 0, 1]
ident int [type: int]
fn test [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
binary [+] [value: int]
ident x [var: int]
M pkg/semantic/testdata/types/fn_struct_self_shadow.snow.want => pkg/semantic/testdata/types/fn_struct_self_shadow.snow.want +1 -3
@@ 4,9 4,7 @@ file testdata/fn_struct_self_shadow.snow [0, 0, 1]
ident int [type: int]
fn get [let: () -> int]
ident int [type: int]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
return
select [let: int]
ident self [let: struct S]
M pkg/semantic/testdata/types/fn_struct_self_uses.snow.want => pkg/semantic/testdata/types/fn_struct_self_uses.snow.want +1 -3
@@ 1,8 1,6 @@
file testdata/fn_struct_self_uses.snow [0, 0, 1]
struct S [0, 1, 0] [type: struct S]
fn set [let: () -> void]
- block [2]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [1]
var: self [var: int]
ident int [type: int]
M pkg/semantic/testdata/types/struct_var_expr_call_method.snow.want => pkg/semantic/testdata/types/struct_var_expr_call_method.snow.want +2 -6
@@ 12,9 12,7 @@ file testdata/struct_var_expr_call_method.snow [0, 1, 1]
ident y [let: int]
fn f [let: () -> int]
ident int [type: int]
- block [3]
- let: self [let: struct S]
- ident S [type: struct S]
+ block [2]
assign
ident x [var: int]
binary [+] [value: int]
@@ 24,9 22,7 @@ file testdata/struct_var_expr_call_method.snow [0, 1, 1]
ident x [var: int]
ref fn f2 [let: () -> int]
ident int [type: int]
- block [5]
- var: self [var: struct S]
- ident S [type: struct S]
+ block [4]
assign
ident x [var: int]
binary [+] [value: int]
M pkg/semantic/translate_pass.go => pkg/semantic/translate_pass.go +29 -14
@@ 106,11 106,12 @@ func (t *translateVisitor) Visit(n ast.Node) ast.Visitor {
}
// parameters and body (possibly missing for external functions) are in a new scope
- tt := t.clone(t.scope.New(&fn))
+ bodyScope := t.scope.New(&fn)
+ tt := t.clone(bodyScope)
tt.preventBlockScope = true
if str, ok := fn.scope.Owner.(*Struct); ok {
fn.MethodOf = str
- generateSelfVar(&fn, n.Body)
+ generateSelfVar(&fn, n.Body, bodyScope)
}
for i, param := range n.Signature.Params {
ast.Walk(tt, param)
@@ 498,23 499,37 @@ func (t *translateVisitor) buildVarOrExpr(kw token.Token, ident *ast.Ident, typ
return v.TypeExpr
}
-func generateSelfVar(fn *Fn, body *ast.Block) {
+func generateSelfVar(fn *Fn, body *ast.Block, bodyScope *Scope) {
// nothing to do if there is no body
if body == nil {
return
}
- // make "self" a var if the function is a ref
- kw := token.Let
+ /*
+ // TODO: remove if that works...
+ // make "self" a var if the function is a ref
+ kw := token.Let
+ if fn.IsRef {
+ kw = token.Var
+ }
+ self := &ast.VarDecl{
+ Kw: kw,
+ KwPos: body.Pos(),
+ Name: &ast.Ident{Name: SelfVarName, IdentPos: body.Pos()},
+ Colon: body.Pos(),
+ Type: &ast.Ident{Name: fn.MethodOf.Ident(), IdentPos: body.Pos()},
+ }
+ body.Stmts = append([]ast.Stmt{self}, body.Stmts...)
+ */
+ // just register the "self" var in the scope
+ var self Var
+ self.Ctx = Immutable
if fn.IsRef {
- kw = token.Var
- }
- self := &ast.VarDecl{
- Kw: kw,
- KwPos: body.Pos(),
- Name: &ast.Ident{Name: SelfVarName, IdentPos: body.Pos()},
- Colon: body.Pos(),
- Type: &ast.Ident{Name: fn.MethodOf.Ident(), IdentPos: body.Pos()},
+ self.Ctx = Mutable
}
- body.Stmts = append([]ast.Stmt{self}, body.Stmts...)
+ self.pos = body.Pos()
+ self.scope = bodyScope
+ self.ident = SelfVarName
+ self.typ = &StructType{Decl: fn.MethodOf}
+ bodyScope.Register(SelfVarName, &self)
}