Skip to content

Commit 1ff7ab0

Browse files
fix: now we're able to add complex arithmetic expressions
1 parent 2b7bb06 commit 1ff7ab0

File tree

7 files changed

+165
-10
lines changed

7 files changed

+165
-10
lines changed

ast/ast.go

+8
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,15 @@ type Block struct {
3838
Stmts []Stmt
3939
}
4040

41+
type Term struct {
42+
LParen int
43+
RParen int
44+
ExprStmt Stmt
45+
}
46+
4147
func (*BasicLit) Expr() {}
48+
func (*Term) Expr() {}
49+
func (*Term) Stmt() {}
4250

4351
type ExprStmt interface {
4452
Expr()

gen/gen.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package _gen
2+
3+
import (
4+
"strings"
5+
6+
_ast "github.com/ProgrammingMuffin/Fig/ast"
7+
)
8+
9+
var Module strings.Builder
10+
11+
func VisitTree(node _ast.Node) string {
12+
switch x := node.(type) {
13+
case *_ast.FuncDecl:
14+
Module.WriteString("void " + x.FuncName.Value + "()")
15+
VisitBlock(x.Block)
16+
}
17+
return Module.String()
18+
}
19+
20+
func VisitBlock(node _ast.Block) {
21+
Module.WriteString("{")
22+
for _, stmt := range node.Stmts {
23+
VisitStatement(stmt)
24+
Module.WriteString(";")
25+
}
26+
Module.WriteString("}\n")
27+
}
28+
29+
func VisitStatement(node _ast.Stmt) {
30+
switch x := node.(type) {
31+
case *_ast.AssignStmt:
32+
Module.WriteString("int " + x.Lhs.Value + " = ")
33+
VisitStatement(x.Rhs)
34+
case *_ast.BinaryExpr:
35+
switch y := x.Lhs.(type) {
36+
case *_ast.BasicLit:
37+
Module.WriteString(y.Value + " " + x.Op.Type + " ")
38+
case *_ast.BinaryExpr:
39+
VisitStatement(y)
40+
case *_ast.Term:
41+
Module.WriteString("( ")
42+
switch z := y.ExprStmt.(type) {
43+
case *_ast.BinaryExpr:
44+
VisitStatement(z)
45+
}
46+
Module.WriteString(" ) " + x.Op.Type + " ")
47+
}
48+
switch y := x.Rhs.(type) {
49+
case *_ast.BasicLit:
50+
Module.WriteString(y.Value)
51+
case *_ast.BinaryExpr:
52+
VisitStatement(y)
53+
}
54+
}
55+
}

go.mod

+9
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,17 @@ go 1.21.5
55
require (
66
github.com/k0kubun/pp v3.0.1+incompatible // indirect
77
github.com/k0kubun/pp/v3 v3.2.0 // indirect
8+
github.com/kr/pretty v0.2.0 // indirect
9+
github.com/kr/text v0.2.0 // indirect
10+
github.com/llir/ll v0.0.0-20220802044011-65001c0fb73c // indirect
11+
github.com/llir/llvm v0.3.6 // indirect
812
github.com/mattn/go-colorable v0.1.13 // indirect
913
github.com/mattn/go-isatty v0.0.16 // indirect
14+
github.com/mewmew/float v0.0.0-20201204173432-505706aa38fa // indirect
15+
github.com/pkg/errors v0.9.1 // indirect
16+
golang.org/x/mod v0.4.2 // indirect
1017
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
1118
golang.org/x/text v0.3.7 // indirect
19+
golang.org/x/tools v0.1.4 // indirect
20+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
1221
)

lex/lex.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ type RBrace struct {
2323
End int
2424
}
2525

26+
type LParen struct {
27+
Token
28+
Pos int
29+
End int
30+
}
31+
32+
type RParen struct {
33+
Token
34+
Pos int
35+
End int
36+
}
37+
2638
type DoubleQuote struct {
2739
Token
2840
Pos int
@@ -122,11 +134,15 @@ func LexSourceFile(sourceFile string) []Token {
122134
tokens = append(tokens, Number{Pos: pos, End: end, Value: numberValue.String()})
123135
numberValue.Reset()
124136
}
125-
} else if isSymbol(char) && (unicode.IsLetter(rune(data[index+1])) || unicode.IsNumber(rune(data[index+1])) || data[index+1] == ' ' || data[index+1] == '\t' || data[index+1] == '\n') && !isSymbol(data[index+1]) {
137+
} else if isSymbol(char) && (unicode.IsLetter(rune(data[index+1])) || unicode.IsNumber(rune(data[index+1])) || data[index+1] == '(' || data[index+1] == ')' || data[index+1] == ' ' || data[index+1] == '\t' || data[index+1] == '\n') {
126138
if symbol.Len() != 0 {
127139
pos := index - len(symbol.String())
128140
end := index
129141
switch symbol.String() {
142+
case "(":
143+
tokens = append(tokens, LParen{Pos: pos, End: end})
144+
case ")":
145+
tokens = append(tokens, RParen{Pos: pos, End: end})
130146
case "{":
131147
tokens = append(tokens, LBrace{Pos: pos, End: end})
132148
case "}":

main.fig

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
func Test {
2-
x = 1 + 2 * 3
2+
x = ((1 + 2) * (1 + (3 + 5)))
33
}
44

55
func Test2 {

main.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
package main
22

33
import (
4+
"fmt"
5+
6+
_gen "github.com/ProgrammingMuffin/Fig/gen"
47
_lex "github.com/ProgrammingMuffin/Fig/lex"
58
_parse "github.com/ProgrammingMuffin/Fig/parse"
9+
"github.com/k0kubun/pp/v3"
610
)
711

812
func main() {
913
tokens := _lex.LexSourceFile("main.fig")
10-
_ = _parse.ParseTokens(tokens)
14+
ast := _parse.ParseTokens(tokens)
15+
pp.Println(ast)
16+
for _, astVal := range ast {
17+
_gen.VisitTree(astVal)
18+
}
19+
fmt.Println(_gen.Module.String())
1120
}

parse/parse.go

+65-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
_ast "github.com/ProgrammingMuffin/Fig/ast"
99
_lex "github.com/ProgrammingMuffin/Fig/lex"
10-
"github.com/k0kubun/pp/v3"
1110
)
1211

1312
var Scan int = 0
@@ -123,15 +122,26 @@ OUTSIDE:
123122
}
124123

125124
func ParseStatement() (_ast.Stmt, error) {
125+
switch Tokens[Scan].(type) {
126+
case _lex.LParen:
127+
term, err := ParseTerm()
128+
if err != nil {
129+
return nil, err
130+
}
131+
expr, err := ParseStatement()
132+
switch x := expr.(type) {
133+
case *_ast.BinaryExpr:
134+
x.Lhs = term
135+
}
136+
return expr, nil
137+
}
126138
if (Scan + 1) < len(Tokens) {
127139
switch x := Tokens[Scan+1].(type) {
128140
case _lex.Operator:
129141
if x.Kind == "=" {
130142
return ParseAssignStatement()
131143
} else if x.Kind == "+" || x.Kind == "-" || x.Kind == "*" || x.Kind == "/" {
132-
stmt, err := ParseBinaryExpr(nil, 1)
133-
pp.SetDefaultMaxDepth(-1)
134-
pp.Println(stmt)
144+
stmt, err := ParseBinaryExpr(nil, nil, 1)
135145
return stmt, err
136146
}
137147
default:
@@ -163,19 +173,57 @@ func ParseAssignStatement() (_ast.Stmt, error) {
163173
switch Tokens[Scan].(type) {
164174
case _lex.Ident:
165175
return ParseStatement()
176+
case _lex.LParen:
177+
term, err := ParseTerm()
178+
if err != nil {
179+
return nil, err
180+
}
181+
_, err = ParseBinaryExpr(nil, term, 0)
182+
if err != nil {
183+
return nil, err
184+
}
185+
stmt.Rhs = term
186+
return &stmt, nil
166187
case _lex.Number:
167-
return ParseStatement()
188+
nextStmt, err := ParseStatement()
189+
if err != nil {
190+
return nil, err
191+
}
192+
stmt.Rhs = nextStmt
193+
return &stmt, nil
168194
}
169195
fmt.Println("error parsing assignment statement")
170196
return nil, nil
171197
}
172198

173-
func ParseBinaryExpr(prev *_ast.BinaryExpr, prec int) (*_ast.BinaryExpr, error) {
199+
func ParseTerm() (*_ast.Term, error) {
200+
term := _ast.Term{}
201+
err := SafeInc()
202+
if err != nil {
203+
return nil, err
204+
}
205+
stmt, err := ParseStatement()
206+
if err != nil {
207+
return nil, err
208+
}
209+
SafeInc()
210+
switch Tokens[Scan].(type) {
211+
case _lex.RParen:
212+
term.ExprStmt = stmt
213+
return &term, nil
214+
default:
215+
return nil, nil
216+
}
217+
}
218+
219+
func ParseBinaryExpr(prev *_ast.BinaryExpr, prevTerm _ast.ExprStmt, prec int) (*_ast.BinaryExpr, error) {
174220
binaryExpr := _ast.BinaryExpr{}
175221
if Scan+2 < len(Tokens) {
176222
switch x := Tokens[Scan+1].(type) {
177223
case _lex.RBrace:
178224
return nil, nil
225+
case _lex.RParen:
226+
return nil, nil
179227
case _lex.Operator:
180228
fmt.Println("operator is: ", x)
181229
prec := 1
@@ -190,11 +238,21 @@ func ParseBinaryExpr(prev *_ast.BinaryExpr, prec int) (*_ast.BinaryExpr, error)
190238
}
191239
if prev != nil {
192240
prev.Rhs = &binaryExpr
241+
} else if prevTerm != nil {
242+
binaryExpr.Lhs = prevTerm
193243
}
194244
binaryExpr.Op = _ast.Operator{Type: x.Kind}
195245
SafeInc()
196246
SafeInc()
197-
expr, err := ParseBinaryExpr(&binaryExpr, prec)
247+
switch Tokens[Scan].(type) {
248+
case _lex.LParen:
249+
term, err := ParseTerm()
250+
if err != nil {
251+
return nil, err
252+
}
253+
binaryExpr.Rhs = term
254+
}
255+
expr, err := ParseBinaryExpr(&binaryExpr, nil, prec)
198256
if err != nil {
199257
return nil, err
200258
}

0 commit comments

Comments
 (0)