Skip to content

Commit

Permalink
test: test for parsing empty statements
Browse files Browse the repository at this point in the history
  • Loading branch information
Aden-Q committed May 8, 2024
1 parent e940616 commit 96dd14c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 32 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ Monkey is an interpreted language written in Go. *This project is still under de
+ [ ] feat: switch between multiple value representation system using some flag
+ [ ] feat: class (object system)
+ [ ] feat: configuration with yaml or envrc
+ [ ] feat: edge cases for those operators
+ [ ] feat: integer division operator and float division operator
+ [ ] feat: reference integer literal as constant, simulate some static memory space for literals of integer, strings, etc.
+ [ ] feat: immutable types
+ [ ] feat: integer overflow problem

## References

Expand Down
43 changes: 30 additions & 13 deletions internal/object/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ const (
NIL_OBJ = "NIL"
)

// boolean literal objects
var (
TRUE = NewBoolean(true)
FALSE = NewBoolean(false)
NIL = NewNil()
)

// interface compliance check
var _ Object = (*Integer)(nil)
var _ Object = (*Boolean)(nil)
Expand All @@ -18,13 +25,20 @@ type ObjectType string
type Object interface {
Type() ObjectType
Inspect() string
IsTruthy() bool
}

// Integer
type Integer struct {
Value int64
}

func NewInteger(value int64) *Integer {
return &Integer{
Value: value,
}
}

func (i *Integer) Type() ObjectType {
return INTEGER_OBJ
}
Expand All @@ -33,16 +47,20 @@ func (i *Integer) Inspect() string {
return strconv.FormatInt(i.Value, 10)
}

func NewInteger(value int64) *Integer {
return &Integer{
Value: value,
}
func (i *Integer) IsTruthy() bool {
return i.Value != 0
}

type Boolean struct {
Value bool
}

func NewBoolean(value bool) *Boolean {
return &Boolean{
Value: value,
}
}

func (b *Boolean) Type() ObjectType {
return BOOLEAN_OBJ
}
Expand All @@ -51,14 +69,15 @@ func (b *Boolean) Inspect() string {
return strconv.FormatBool(b.Value)
}

func NewBoolean(value bool) *Boolean {
return &Boolean{
Value: value,
}
func (b *Boolean) IsTruthy() bool {
return b.Value == true

Check failure on line 73 in internal/object/object.go

View workflow job for this annotation

GitHub Actions / lint-build-test

S1002: should omit comparison to bool constant, can be simplified to `b.Value` (gosimple)
}

// Nil represents the absence of any value
type Nil struct {
type Nil struct{}

func NewNil() *Nil {
return &Nil{}
}

func (n *Nil) Type() ObjectType {
Expand All @@ -69,8 +88,6 @@ func (n *Nil) Inspect() string {
return "nil"
}

func NewNil(value bool) *Boolean {
return &Boolean{
Value: value,
}
func (n *Nil) IsTruthy() bool {
return false
}
10 changes: 9 additions & 1 deletion internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ func (p *parser) ParseProgram(text string) (*ast.Program, []error) {

// in each iteration of the for loop here, we parse a single statement separated by a semicolon ;
for p.curToken.Type != token.EOF {
if p.curToken.Type == token.SEMICOLON {
// this is an empty statement (i.e. only a single ; token in the whole statement)
// treat it as an empty expression statement, instead of ignoring it
program.Statements = append(program.Statements, ast.NewExpressionStatement(nil))
p.nextToken()
continue
}

// parse a single statement every time
stmt, err := p.parseStatment()
if err != nil {
Expand Down Expand Up @@ -157,7 +165,7 @@ func (p *parser) parseStatment() (ast.Statement, error) {
// so that we can continue parsing the following statements
p.nextToken()

return stmt, err
return stmt, nil
}

// parseLetStatement parses a single let statement
Expand Down
35 changes: 17 additions & 18 deletions internal/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,23 +392,22 @@ var _ = Describe("Parser", func() {
})
})

// TODO: parse empty statement
// Context("special statements", func() {
// It("empty statement", func() {
// text = `
// ;
// `
// expectedProgram := &ast.Program{
// Statements: []ast.Statement{
// ast.NewExpressionStatement(nil),
// },
// }
// expectedErrors := []error{}

// program, errs = p.ParseProgram(text)
// Expect(program).To(Equal(expectedProgram))
// Expect(errs).To(Equal(expectedErrors))
// })
// })
Context("special statements", func() {
It("empty statement", func() {
text = `
;
`
expectedProgram := &ast.Program{
Statements: []ast.Statement{
ast.NewExpressionStatement(nil),
},
}
expectedErrors := []error{}

program, errs = p.ParseProgram(text)
Expect(program).To(Equal(expectedProgram))
Expect(errs).To(Equal(expectedErrors))
})
})
})
})

0 comments on commit 96dd14c

Please sign in to comment.