summaryrefslogtreecommitdiff
path: root/symbol
diff options
context:
space:
mode:
Diffstat (limited to 'symbol')
-rw-r--r--symbol/kind_string.go30
-rw-r--r--symbol/symbol.go92
2 files changed, 122 insertions, 0 deletions
diff --git a/symbol/kind_string.go b/symbol/kind_string.go
new file mode 100644
index 0000000..07dbd6a
--- /dev/null
+++ b/symbol/kind_string.go
@@ -0,0 +1,30 @@
+// Code generated by "stringer -type=Kind"; DO NOT EDIT.
+
+package symbol
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[Value-0]
+ _ = x[Type-1]
+ _ = x[Label-2]
+ _ = x[Const-3]
+ _ = x[Var-4]
+ _ = x[Func-5]
+ _ = x[Pkg-6]
+}
+
+const _Kind_name = "ValueTypeLabelConstVarFuncPkg"
+
+var _Kind_index = [...]uint8{0, 5, 9, 14, 19, 22, 26, 29}
+
+func (i Kind) String() string {
+ idx := int(i) - 0
+ if i < 0 || idx >= len(_Kind_index)-1 {
+ return "Kind(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _Kind_name[_Kind_index[idx]:_Kind_index[idx+1]]
+}
diff --git a/symbol/symbol.go b/symbol/symbol.go
new file mode 100644
index 0000000..31869fd
--- /dev/null
+++ b/symbol/symbol.go
@@ -0,0 +1,92 @@
+// Package symbol implements symbol utilities.
+package symbol
+
+import (
+ "fmt"
+ "go/constant"
+ "strings"
+
+ "github.com/mvertes/parscan/vm"
+)
+
+// Kind represents the symbol kind.
+type Kind int
+
+// Symbol kinds.
+const (
+ Value Kind = iota // a value defined in the runtime
+ Type // a type
+ Label // a label indicating a position in the VM code
+ Const // a constant
+ Var // a variable, located in the VM memory
+ Func // a function, located in the VM code
+ Pkg // a package
+)
+
+//go:generate stringer -type=Kind
+
+// UnsetAddr denotes an unset symbol index (vs 0).
+const UnsetAddr = -65535
+
+// Symbol structure used in parser and compiler.
+type Symbol struct {
+ Kind Kind
+ Index int // address of symbol in frame
+ PkgPath string //
+ Type *vm.Type //
+ Value vm.Value //
+ Cval constant.Value //
+ Local bool // if true address is relative to local frame, otherwise global
+ Used bool //
+}
+
+// Vtype returns the VM type of a symbol.
+func Vtype(s *Symbol) *vm.Type {
+ if s.Type != nil {
+ return s.Type
+ }
+ return vm.TypeOf(s.Value)
+}
+
+// SymMap is a map of Symbols.
+type SymMap map[string]*Symbol
+
+// Add adds a new named symbol value at memory position i.
+func (sm SymMap) Add(i int, name string, v vm.Value, k Kind, t *vm.Type, local bool) {
+ name = strings.TrimPrefix(name, "/")
+ sm[name] = &Symbol{Kind: k, Index: i, Local: local, Value: v, Type: t}
+}
+
+// Get searches for an existing symbol starting from the deepest scope.
+func (sm SymMap) Get(name, scope string) (sym *Symbol, sc string, ok bool) {
+ for {
+ if sym, ok = sm[scope+"/"+name]; ok {
+ return sym, scope, ok
+ }
+ i := strings.LastIndex(scope, "/")
+ if i == -1 {
+ i = 0
+ }
+ if scope = scope[:i]; scope == "" {
+ break
+ }
+ }
+ sym, ok = sm[name]
+ return sym, scope, ok
+}
+
+// Init fills the symbol map with default Go symbols.
+func (sm SymMap) Init() {
+ sm["any"] = &Symbol{Kind: Type, Index: UnsetAddr, Type: vm.TypeOf((*any)(nil)).Elem()}
+ sm["bool"] = &Symbol{Kind: Type, Index: UnsetAddr, Type: vm.TypeOf((*bool)(nil)).Elem()}
+ sm["error"] = &Symbol{Kind: Type, Index: UnsetAddr, Type: vm.TypeOf((*error)(nil)).Elem()}
+ sm["int"] = &Symbol{Kind: Type, Index: UnsetAddr, Type: vm.TypeOf((*int)(nil)).Elem()}
+ sm["string"] = &Symbol{Kind: Type, Index: UnsetAddr, Type: vm.TypeOf((*string)(nil)).Elem()}
+
+ sm["nil"] = &Symbol{Index: UnsetAddr}
+ sm["iota"] = &Symbol{Kind: Const, Index: UnsetAddr}
+ sm["true"] = &Symbol{Index: UnsetAddr, Value: vm.ValueOf(true), Type: vm.TypeOf(true)}
+ sm["false"] = &Symbol{Index: UnsetAddr, Value: vm.ValueOf(false), Type: vm.TypeOf(false)}
+
+ sm["println"] = &Symbol{Index: UnsetAddr, Value: vm.ValueOf(func(v ...any) { fmt.Println(v...) })}
+}