/
struct.go
94 lines (84 loc) · 2.33 KB
/
struct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright 2018 Alexey Krivonogov. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.
package compiler
import (
"reflect"
"strings"
"github.com/gentee/gentee/core"
)
func checkNewType(cmpl *compiler) (string, error) {
token := getToken(cmpl.unit.Lexeme, cmpl.pos)
obj, _ := getType(cmpl)
if obj != nil {
return ``, cmpl.Error(ErrTypeExists, token)
}
if isCapital(token) {
return ``, cmpl.Error(ErrCapitalLetters)
}
if strings.IndexRune(token, '.') >= 0 {
return ``, cmpl.Error(ErrIdent)
}
return token, nil
}
func coStruct(cmpl *compiler) error {
token, err := checkNewType(cmpl)
if err != nil {
return err
}
pType := cmpl.unit.NewType(token, reflect.TypeOf(core.Struct{}), nil).(*core.TypeObject)
pType.Custom = &core.StructType{
Fields: make(map[string]int64),
Types: make([]*core.TypeObject, 0),
}
cmpl.curType = pType
return nil
}
func coStructEnd(cmpl *compiler) error {
cmpl.curType = nil
return nil
}
func coStructLine(cmpl *compiler) error {
if len(cmpl.curType.Custom.Fields) != len(cmpl.curType.Custom.Types) {
return cmpl.Error(ErrName)
}
return nil
}
func coStructType(cmpl *compiler) error {
obj, err := getType(cmpl)
if err != nil {
return err
}
cmpl.curType.Custom.Types = append(cmpl.curType.Custom.Types, obj.(*core.TypeObject))
return nil
}
func coStructName(cmpl *compiler) error {
token := getToken(cmpl.unit.Lexeme, cmpl.pos)
if strings.IndexRune(token, '.') >= 0 {
return cmpl.Error(ErrIdent)
}
if len(cmpl.curType.Custom.Fields) == len(cmpl.curType.Custom.Types) {
return cmpl.Error(ErrLineRCurly)
}
if _, ok := cmpl.curType.Custom.Fields[token]; ok {
return cmpl.Error(ErrStructField, token)
}
if obj, _ := autoType(cmpl, token); obj != nil {
return cmpl.Error(ErrName)
}
cmpl.curType.Custom.Fields[token] = int64(len(cmpl.curType.Custom.Types) - 1)
return nil
}
func structIndex(cmpl *compiler, typeObj *core.TypeObject, field string) (int64, *core.TypeObject, error) {
var (
indField int64
ok bool
)
if typeObj.Custom == nil {
return 0, nil, cmpl.ErrorPos(cmpl.pos-1, ErrStructType, typeObj.GetName())
}
if indField, ok = typeObj.Custom.Fields[field]; !ok {
return 0, nil, cmpl.ErrorPos(cmpl.pos-1, ErrStruct, typeObj.GetName(), field)
}
return indField, typeObj.Custom.Types[indField], nil
}