M go.mod => go.mod +1 -0
@@ 3,6 3,7 @@ module git.sr.ht/~mna/snow
go 1.13
require (
+ github.com/kr/pretty v0.1.0
github.com/kylelemons/godebug v1.1.0
golang.org/x/exp v0.0.0-20191129062945-2f5052295587
)
M go.sum => go.sum +5 -0
@@ 1,6 1,11 @@
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
M pkg/compiler/parser.go => pkg/compiler/parser.go +18 -3
@@ 100,7 100,7 @@ func (p *parser) parseFile() *file {
var stmts []stmt
for p.tok != EOF {
- stmts = append(stmts, p.parseStmt())
+ stmts = append(stmts, p.parseStmt(true))
}
return &file{
@@ 109,7 109,14 @@ func (p *parser) parseFile() *file {
}
}
-func (p *parser) parseStmt() stmt {
+func (p *parser) parseStmt(topLevel bool) stmt {
+ if !topLevel {
+ switch p.tok {
+ case Return:
+ return p.parseReturnStmt()
+ }
+ }
+
switch p.tok {
case Let, Var:
return p.parseVarDef()
@@ 123,6 130,14 @@ func (p *parser) parseStmt() stmt {
}
}
+func (p *parser) parseReturnStmt() *returnStmt {
+ rs := &returnStmt{
+ ret: p.expect(Return),
+ }
+ // TODO: need auto-semicolons here, can't know if there's an expr after
+ return rs
+}
+
func (p *parser) parseVarDef() *varDef {
vd := &varDef{
kw: p.tok,
@@ 267,7 282,7 @@ func (p *parser) parseBlock() *block {
func (p *parser) parseStmtList() []stmt {
var list []stmt
for p.tok != Rbrace && p.tok != EOF {
- list = append(list, p.parseStmt())
+ list = append(list, p.parseStmt(false))
}
return list
}
M pkg/compiler/parser_test.go => pkg/compiler/parser_test.go +1 -0
@@ 43,6 43,7 @@ func TestParser(t *testing.T) {
f := p.parseFile()
p.errors.RemoveMultiples()
parseErr := p.errors.Err()
+ //pretty.Print(f)
var ebuf bytes.Buffer
goscanner.PrintError(&ebuf, parseErr)
M pkg/compiler/scanner.go => pkg/compiler/scanner.go +1 -0
@@ 161,6 161,7 @@ func (s *scanner) ident() string {
for isLetter(s.cur) || isDigit(s.cur) {
s.next()
}
+ // TODO: allow single "!" or "?" at the end
return string(s.src[off:s.off])
}
A pkg/compiler/testdata/fn.snow => pkg/compiler/testdata/fn.snow +1 -0
@@ 0,0 1,1 @@
+fn empty() { }
A pkg/compiler/testdata/fn.snow.err => pkg/compiler/testdata/fn.snow.err +0 -0
A pkg/compiler/testdata/fn.snow.want => pkg/compiler/testdata/fn.snow.want +5 -0
@@ 0,0 1,5 @@
+file [0:14]
+ fn [0:14]
+ ident [empty] [3:8]
+ sig [8:10]
+ block [11:14]
A pkg/compiler/testdata/fn_add.snow.notyet => pkg/compiler/testdata/fn_add.snow.notyet +3 -0
@@ 0,0 1,3 @@
+fn add(x: int, y: int) -> int {
+ return x + y
+}
A pkg/compiler/testdata/fn_naked_return.snow.notyet => pkg/compiler/testdata/fn_naked_return.snow.notyet +4 -0
@@ 0,0 1,4 @@
+fn print(x: int, y: string) {
+ x + y
+ return
+}
M pkg/grammar/grammar.ebnf => pkg/grammar/grammar.ebnf +1 -0
@@ 22,6 22,7 @@ ParamDef = ident ":" ident .
FuncTrailer = "->" ident .
Block = "{" { Stmt } "}" .
+// TODO: expression statement
Stmt = VarDef | ReturnStmt .
ReturnStmt = "return" [ Expr ] .