-
Notifications
You must be signed in to change notification settings - Fork 3
/
repl.go
114 lines (84 loc) · 1.61 KB
/
repl.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"bufio"
"fmt"
"io"
"log"
"os/exec"
"github.com/vapourlang/vapour/lexer"
"github.com/vapourlang/vapour/parser"
"github.com/vapourlang/vapour/transpiler"
)
const PROMPT = "> "
func (v *vapour) replIntro() string {
return "Vapour " + v.version + "\n"
}
func (v *vapour) repl(in io.Reader, out io.Writer, er io.Writer) {
cmd := exec.Command(
"R",
"-s",
"-e",
`f <- file("stdin")
open(f)
while(length(line <- readLines(f, n = 1)) > 0) {
cat(eval(parse(text = line)))
}`,
)
//cmd.Stdout = out
cmd.Stderr = er
cmdIn, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
defer cmdIn.Close()
cmdOut, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
defer cmdOut.Close()
scanner := bufio.NewScanner(in)
fmt.Fprint(out, v.replIntro())
err = cmd.Start()
if err != nil {
log.Fatal(err)
}
for {
fmt.Fprint(out, PROMPT)
scanned := scanner.Scan()
if !scanned {
continue
}
line := scanner.Text()
// lex
l := lexer.NewCode("repl", line+"\n")
l.Run()
if l.HasError() {
fmt.Fprintln(out, l.Errors().String())
continue
}
// parse
p := parser.New(l)
prog := p.Run()
if p.HasError() {
for _, e := range p.Errors() {
fmt.Fprintln(out, e.Message)
}
continue
}
trans := transpiler.New()
trans.Transpile(prog)
code := trans.GetCode()
_, err := io.WriteString(cmdIn, code)
if err != nil {
fmt.Fprint(out, err.Error())
continue
}
res := make([]byte, 1024)
_, err = cmdOut.Read(res)
if err != nil {
fmt.Fprint(out, err.Error())
continue
}
fmt.Fprint(out, string(res)+"\n")
}
}