1
0
forked from x/icebergs
icebergs/base/yac/type.go
2023-04-07 21:41:39 +08:00

155 lines
3.0 KiB
Go

package yac
import (
"strings"
ice "shylinux.com/x/icebergs"
kit "shylinux.com/x/toolkits"
)
type Map struct {
value Any
key Any
}
type Slice struct {
value Any
}
type Interface struct {
index map[string]Function
name string
}
type Struct struct {
index map[string]Any
name string
}
type Field struct {
types Any
tags map[string]string
name string
}
func (s Field) MarshalJSON() ([]byte, error) {
return []byte(kit.Format("%q", s.Format())), nil
}
func (s Field) Format() string {
if len(s.tags) == 0 {
return kit.Format("%s", s.types)
}
res := []string{}
kit.For(s.tags, func(k, v string) { res = append(res, kit.Format("%s:\"%s\"", k, v)) })
return kit.Format("%s `%s`", s.types, strings.Join(res, ice.SP))
}
type Object struct {
value Operater
index Struct
}
func (s Object) Operate(op string, v Any) Any {
switch op {
case "&", "*":
return s
case INSTANCEOF:
if t, ok := v.(Struct); ok {
return Value{list: []Any{s, s.index.name == t.name}}
}
return Value{list: []Any{s, false}}
case IMPLEMENTS:
if t, ok := v.(Interface); ok {
for k, v := range t.index {
if _v, ok := s.index.index[k].(Function); ok {
for i, field := range v.arg {
if i < len(_v.arg) && _v.arg[i].types == field.types {
continue
}
return Value{list: []Any{s, false}}
}
for i, field := range v.res {
if i < len(_v.res) && _v.res[i].types == field.types {
continue
}
return Value{list: []Any{s, false}}
}
} else {
return Value{list: []Any{s, false}}
}
}
}
return Value{list: []Any{s, true}}
case SUBS:
switch v := s.index.index[kit.Format(v)].(type) {
case Function:
v.object = s
return v
}
fallthrough
default:
return s.value.Operate(op, v)
}
return nil
}
const (
MAP = "map"
SLICE = "slice"
STRUCT = "struct"
INTERFACE = "interface"
STRING = "string"
INT = "int"
INSTANCEOF = "instanceof"
IMPLEMENTS = "implements"
CONST = "const"
TYPE = "type"
VAR = "var"
)
func init() {
Index.MergeCommands(ice.Commands{
CONST: {Name: "const a = 1", Hand: func(m *ice.Message, arg ...string) {
if s := _parse_stack(m); s.next(m) == OPEN {
for s.token() != CLOSE {
s.nextLine(m)
s.skip--
s.cals(m, CLOSE)
}
} else {
s.skip--
s.cals(m)
}
}},
TYPE: {Name: "type student struct {", Hand: func(m *ice.Message, arg ...string) {
s := _parse_stack(m)
switch name := s.next(m); s.next(m) {
case ASSIGN:
s.next(m)
fallthrough
default:
switch t := s.types(m).(type) {
case Interface:
t.name = name
s.value(m, name, t)
case Struct:
t.name = name
s.value(m, name, t)
default:
s.value(m, name, t)
}
}
}},
VAR: {Name: "var a = 1", Hand: func(m *ice.Message, arg ...string) {
if s := _parse_stack(m); s.next(m) == OPEN {
for s.token() != CLOSE {
s.nextLine(m)
s.skip--
s.cals(m, CLOSE)
}
} else {
s.skip--
s.cals(m)
}
}},
})
}