Skip to content

Commit 664819e

Browse files
committed
extract Time builtin namespace registration
1 parent 02706c5 commit 664819e

3 files changed

Lines changed: 128 additions & 118 deletions

File tree

docs/architecture.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ Builtins are registered during engine initialization:
129129
- `vibes/builtins_json_regex.go`
130130
- class/object registration helpers in `vibes/interpreter_builtins_data.go` (`JSON`/`Regex` namespace objects)
131131
- duration class registration in `vibes/interpreter_builtins_duration.go`
132+
- time class registration in `vibes/interpreter_builtins_time.go`
132133

133134
## Refactor Constraints
134135

vibes/interpreter.go

Lines changed: 1 addition & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"os"
1010
"strings"
1111
"sync"
12-
"time"
1312
)
1413

1514
// Config controls interpreter execution bounds and enforcement modes.
@@ -73,123 +72,7 @@ func NewEngine(cfg Config) (*Engine, error) {
7372
registerCoreBuiltins(engine)
7473
registerDataBuiltins(engine)
7574
registerDurationBuiltins(engine)
76-
engine.builtins["Time"] = NewObject(map[string]Value{
77-
"new": NewBuiltin("Time.new", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
78-
loc := time.Local
79-
if zone, ok := kwargs["in"]; ok {
80-
parsed, err := parseLocation(zone)
81-
if err != nil {
82-
return NewNil(), err
83-
}
84-
if parsed != nil {
85-
loc = parsed
86-
}
87-
}
88-
t, err := timeFromParts(args, loc)
89-
if err != nil {
90-
return NewNil(), err
91-
}
92-
return NewTime(t), nil
93-
}),
94-
"local": NewBuiltin("Time.local", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
95-
t, err := timeFromParts(args, time.Local)
96-
if err != nil {
97-
return NewNil(), err
98-
}
99-
return NewTime(t), nil
100-
}),
101-
"mktime": NewAutoBuiltin("Time.mktime", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
102-
t, err := timeFromParts(args, time.Local)
103-
if err != nil {
104-
return NewNil(), err
105-
}
106-
return NewTime(t), nil
107-
}),
108-
"utc": NewBuiltin("Time.utc", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
109-
t, err := timeFromParts(args, time.UTC)
110-
if err != nil {
111-
return NewNil(), err
112-
}
113-
return NewTime(t), nil
114-
}),
115-
"gm": NewAutoBuiltin("Time.gm", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
116-
t, err := timeFromParts(args, time.UTC)
117-
if err != nil {
118-
return NewNil(), err
119-
}
120-
return NewTime(t), nil
121-
}),
122-
"at": NewBuiltin("Time.at", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
123-
if len(args) != 1 {
124-
return NewNil(), fmt.Errorf("Time.at expects seconds since epoch") //nolint:staticcheck // class.method reference
125-
}
126-
var loc *time.Location
127-
if in, ok := kwargs["in"]; ok {
128-
parsed, err := parseLocation(in)
129-
if err != nil {
130-
return NewNil(), err
131-
}
132-
loc = parsed
133-
}
134-
t, err := timeFromEpoch(args[0], loc)
135-
if err != nil {
136-
return NewNil(), err
137-
}
138-
return NewTime(t), nil
139-
}),
140-
"now": NewAutoBuiltin("Time.now", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
141-
if len(args) > 0 {
142-
return NewNil(), fmt.Errorf("Time.now does not take positional arguments") //nolint:staticcheck // class.method reference
143-
}
144-
loc := time.Local
145-
if in, ok := kwargs["in"]; ok {
146-
parsed, err := parseLocation(in)
147-
if err != nil {
148-
return NewNil(), err
149-
}
150-
if parsed != nil {
151-
loc = parsed
152-
}
153-
}
154-
return NewTime(time.Now().In(loc)), nil
155-
}),
156-
"parse": NewBuiltin("Time.parse", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
157-
if len(args) < 1 || len(args) > 2 || args[0].Kind() != KindString {
158-
return NewNil(), fmt.Errorf("Time.parse expects a time string and optional layout") //nolint:staticcheck // class.method reference
159-
}
160-
for key := range kwargs {
161-
if key != "in" {
162-
return NewNil(), fmt.Errorf("Time.parse unknown keyword %q", key) //nolint:staticcheck // class.method reference
163-
}
164-
}
165-
166-
layout := ""
167-
hasLayout := false
168-
if len(args) == 2 {
169-
if args[1].Kind() == KindString {
170-
layout = args[1].String()
171-
hasLayout = true
172-
} else if args[1].Kind() != KindNil {
173-
return NewNil(), fmt.Errorf("Time.parse layout must be string") //nolint:staticcheck // class.method reference
174-
}
175-
}
176-
177-
var loc *time.Location
178-
if in, ok := kwargs["in"]; ok {
179-
parsed, err := parseLocation(in)
180-
if err != nil {
181-
return NewNil(), err
182-
}
183-
loc = parsed
184-
}
185-
186-
t, err := parseTimeString(args[0].String(), layout, hasLayout, loc)
187-
if err != nil {
188-
return NewNil(), err
189-
}
190-
return NewTime(t), nil
191-
}),
192-
})
75+
registerTimeBuiltins(engine)
19376

19477
return engine, nil
19578
}

vibes/interpreter_builtins_time.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package vibes
2+
3+
import (
4+
"fmt"
5+
"time"
6+
)
7+
8+
func registerTimeBuiltins(engine *Engine) {
9+
engine.builtins["Time"] = NewObject(map[string]Value{
10+
"new": NewBuiltin("Time.new", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
11+
loc := time.Local
12+
if zone, ok := kwargs["in"]; ok {
13+
parsed, err := parseLocation(zone)
14+
if err != nil {
15+
return NewNil(), err
16+
}
17+
if parsed != nil {
18+
loc = parsed
19+
}
20+
}
21+
t, err := timeFromParts(args, loc)
22+
if err != nil {
23+
return NewNil(), err
24+
}
25+
return NewTime(t), nil
26+
}),
27+
"local": NewBuiltin("Time.local", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
28+
t, err := timeFromParts(args, time.Local)
29+
if err != nil {
30+
return NewNil(), err
31+
}
32+
return NewTime(t), nil
33+
}),
34+
"mktime": NewAutoBuiltin("Time.mktime", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
35+
t, err := timeFromParts(args, time.Local)
36+
if err != nil {
37+
return NewNil(), err
38+
}
39+
return NewTime(t), nil
40+
}),
41+
"utc": NewBuiltin("Time.utc", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
42+
t, err := timeFromParts(args, time.UTC)
43+
if err != nil {
44+
return NewNil(), err
45+
}
46+
return NewTime(t), nil
47+
}),
48+
"gm": NewAutoBuiltin("Time.gm", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
49+
t, err := timeFromParts(args, time.UTC)
50+
if err != nil {
51+
return NewNil(), err
52+
}
53+
return NewTime(t), nil
54+
}),
55+
"at": NewBuiltin("Time.at", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
56+
if len(args) != 1 {
57+
return NewNil(), fmt.Errorf("Time.at expects seconds since epoch") //nolint:staticcheck // class.method reference
58+
}
59+
var loc *time.Location
60+
if in, ok := kwargs["in"]; ok {
61+
parsed, err := parseLocation(in)
62+
if err != nil {
63+
return NewNil(), err
64+
}
65+
loc = parsed
66+
}
67+
t, err := timeFromEpoch(args[0], loc)
68+
if err != nil {
69+
return NewNil(), err
70+
}
71+
return NewTime(t), nil
72+
}),
73+
"now": NewAutoBuiltin("Time.now", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
74+
if len(args) > 0 {
75+
return NewNil(), fmt.Errorf("Time.now does not take positional arguments") //nolint:staticcheck // class.method reference
76+
}
77+
loc := time.Local
78+
if in, ok := kwargs["in"]; ok {
79+
parsed, err := parseLocation(in)
80+
if err != nil {
81+
return NewNil(), err
82+
}
83+
if parsed != nil {
84+
loc = parsed
85+
}
86+
}
87+
return NewTime(time.Now().In(loc)), nil
88+
}),
89+
"parse": NewBuiltin("Time.parse", func(exec *Execution, receiver Value, args []Value, kwargs map[string]Value, block Value) (Value, error) {
90+
if len(args) < 1 || len(args) > 2 || args[0].Kind() != KindString {
91+
return NewNil(), fmt.Errorf("Time.parse expects a time string and optional layout") //nolint:staticcheck // class.method reference
92+
}
93+
for key := range kwargs {
94+
if key != "in" {
95+
return NewNil(), fmt.Errorf("Time.parse unknown keyword %q", key) //nolint:staticcheck // class.method reference
96+
}
97+
}
98+
99+
layout := ""
100+
hasLayout := false
101+
if len(args) == 2 {
102+
if args[1].Kind() == KindString {
103+
layout = args[1].String()
104+
hasLayout = true
105+
} else if args[1].Kind() != KindNil {
106+
return NewNil(), fmt.Errorf("Time.parse layout must be string") //nolint:staticcheck // class.method reference
107+
}
108+
}
109+
110+
var loc *time.Location
111+
if in, ok := kwargs["in"]; ok {
112+
parsed, err := parseLocation(in)
113+
if err != nil {
114+
return NewNil(), err
115+
}
116+
loc = parsed
117+
}
118+
119+
t, err := parseTimeString(args[0].String(), layout, hasLayout, loc)
120+
if err != nil {
121+
return NewNil(), err
122+
}
123+
return NewTime(t), nil
124+
}),
125+
})
126+
}

0 commit comments

Comments
 (0)