Skip to content

Commit 67e88de

Browse files
committed
props: add Kernel#read
1 parent 8acc39b commit 67e88de

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

evaluator/eval_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10379,6 +10379,36 @@ func TestEvalAssertRaises(t *testing.T) {
1037910379
}
1038010380
}
1038110381

10382+
func TestEvalRead(t *testing.T) {
10383+
tests := []struct {
10384+
input string
10385+
expected object.PanObject
10386+
}{
10387+
{
10388+
`read("testdata/sample.txt")`,
10389+
object.NewPanStr("dummy\n"),
10390+
},
10391+
{
10392+
`read()`,
10393+
object.NewTypeErr("read requires at least 1 arg"),
10394+
},
10395+
{
10396+
`read(1)`,
10397+
object.NewTypeErr("1 cannot be treated as str"),
10398+
},
10399+
{
10400+
`read("testdata/notfound.txt")`,
10401+
object.NewFileNotFoundErr(`"testdata/notfound.txt" cannot be opened: open testdata/notfound.txt: no such file or directory`),
10402+
},
10403+
// TODO: add non-text options
10404+
}
10405+
10406+
for _, tt := range tests {
10407+
actual := testEval(t, tt.input)
10408+
testValue(t, actual, tt.expected)
10409+
}
10410+
}
10411+
1038210412
func TestEvalTry(t *testing.T) {
1038310413
tests := []struct {
1038410414
input string

evaluator/testdata/sample.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dummy

props/kernel_props.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package props
33
import (
44
"fmt"
55
"os"
6+
"path/filepath"
67

78
"github.com/Syuparn/pangaea/object"
89
)
@@ -123,5 +124,37 @@ func KernelProps(propContainer map[string]object.PanObject) map[string]object.Pa
123124
),
124125
"import": propContainer["Kernel_import"],
125126
"invite!": propContainer["Kernel_invite!"],
127+
"read": f(
128+
func(
129+
env *object.Env, kwargs *object.PanObj, args ...object.PanObject,
130+
) object.PanObject {
131+
if len(args) < 1 {
132+
return object.NewTypeErr("read requires at least 1 arg")
133+
}
134+
135+
pathObj, ok := object.TraceProtoOfStr(args[0])
136+
if !ok {
137+
return object.NewTypeErr(
138+
fmt.Sprintf("%s cannot be treated as str", args[0].Repr()))
139+
}
140+
141+
filePath := pathObj.Value
142+
// HACK: find relative file path
143+
if p, ok := env.Get(object.GetSymHash(object.SourcePathVar)); ok {
144+
if p.Type() != object.StrType {
145+
return object.NewTypeErr(fmt.Sprintf("%s %s must be str", object.SourcePathVar, p.Inspect()))
146+
}
147+
filePath = filepath.Join(filepath.Dir(filePath), filePath)
148+
}
149+
150+
b, err := os.ReadFile(filePath)
151+
if err != nil {
152+
return object.NewFileNotFoundErr(
153+
fmt.Sprintf("%s cannot be opened: %s", args[0].Repr(), err.Error()))
154+
}
155+
156+
return object.NewPanStr(string(b))
157+
},
158+
),
126159
}
127160
}

0 commit comments

Comments
 (0)