/
compile_stmt.go
128 lines (111 loc) · 2.68 KB
/
compile_stmt.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package compiler
import (
"fmt"
"go/ast"
"go/token"
"github.com/paralin/goscript/types"
"github.com/sanity-io/litter"
)
// WriteStmt writes a statement to the output.
func (c *GoToTSCompiler) WriteStmt(a ast.Stmt) {
switch exp := a.(type) {
case *ast.BlockStmt:
c.WriteStmtBlock(exp)
case *ast.AssignStmt:
c.WriteStmtAssign(exp)
case *ast.ReturnStmt:
c.WriteStmtReturn(exp)
case *ast.IfStmt:
c.WriteStmtIf(exp)
case *ast.ExprStmt:
c.WriteStmtExpr(exp)
default:
c.tsw.WriteComment(fmt.Sprintf("unknown statement: %s\n", litter.Sdump(a)))
}
}
// WriteStmtIf writes an if statement.
func (s *GoToTSCompiler) WriteStmtIf(exp *ast.IfStmt) {
if exp.Init != nil {
s.tsw.WriteLiterally("{")
s.tsw.Indent(1)
s.WriteStmt(exp.Init)
defer func() {
s.tsw.Indent(-1)
s.tsw.WriteLiterally("}")
}()
}
s.tsw.WriteLiterally("if (")
s.WriteExpr(exp.Cond, true)
s.tsw.WriteLiterally(") ")
if exp.Body != nil {
s.WriteStmtBlock(exp.Body)
} else {
s.tsw.WriteLine("{}")
}
}
// WriteStmtReturn writes a return statement.
func (c *GoToTSCompiler) WriteStmtReturn(exp *ast.ReturnStmt) {
c.tsw.WriteLiterally("return ")
for i, res := range exp.Results {
if i != 0 {
c.tsw.WriteLiterally(", ")
}
c.WriteExpr(res, false)
}
c.tsw.WriteLine(";")
}
// WriteStmtBlock writes a block statement.
func (c *GoToTSCompiler) WriteStmtBlock(exp *ast.BlockStmt) {
if exp == nil {
c.tsw.WriteLine("{}")
return
}
if exp.Lbrace.IsValid() {
c.tsw.WriteLine("{")
c.tsw.Indent(1)
}
for _, stmt := range exp.List {
c.WriteStmt(stmt)
}
if exp.Rbrace.IsValid() {
c.tsw.Indent(-1)
c.tsw.WriteLine("}")
}
}
/*TODO:
// CompilePackage attempts to build a particular package in the gopath.
Compiler.prototype.CompilePackage = function(ctx: context.Context, pkgPath: string) {
pkgCompiler, err = // expr: &ast.CallExpr{
figure out how to determine if let is required here
*/
// WriteStmtAssign writes an assign statement.
func (c *GoToTSCompiler) WriteStmtAssign(exp *ast.AssignStmt) {
// TODO: determine if anything special is required here
// c.tsw.WriteComment(exp.Tok.String())
if exp.Tok == token.DEFINE {
c.tsw.WriteLiterally("let ")
}
for i, l := range exp.Lhs {
if i != 0 {
c.tsw.WriteLiterally(", ")
}
c.WriteExpr(l, true)
}
c.tsw.WriteLiterally(" ")
tokStr, ok := types.TokenToTs(exp.Tok)
if !ok {
c.tsw.WriteLiterally("?= ")
c.tsw.WriteComment("Unknown token " + exp.Tok.String())
} else {
c.tsw.WriteLiterally(tokStr)
}
c.tsw.WriteLiterally(" ")
for _, r := range exp.Rhs {
c.WriteExpr(r, true)
}
c.tsw.WriteLine(";")
}
// WriteStmtExpr writes an expr statement.
func (c *GoToTSCompiler) WriteStmtExpr(exp *ast.ExprStmt) {
c.WriteExpr(exp.X, true)
}