Improve code quality
This commit is contained in:
parent
5edad332cd
commit
3f260e7ffd
11 changed files with 95 additions and 45 deletions
|
|
@ -78,7 +78,10 @@ func TestAll(t *testing.T) {
|
|||
c := NewCompiler()
|
||||
|
||||
t.Log("Compiling parse tree")
|
||||
c.Compile(tree)
|
||||
err = c.Compile(tree)
|
||||
if err != nil {
|
||||
t.Fatalf("Compiler had an error: %s", err)
|
||||
}
|
||||
|
||||
printChunk(t, name, c.Chunk)
|
||||
|
||||
|
|
@ -108,7 +111,7 @@ func BenchmarkAll(b *testing.B) {
|
|||
tree, _ := p.Parse()
|
||||
|
||||
c := NewCompiler()
|
||||
c.Compile(tree)
|
||||
_ = c.Compile(tree)
|
||||
|
||||
vm := NewVM(c.Chunk, 256, 256)
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,10 @@ func (c *Compiler) Compile(tree Node) error {
|
|||
c.addConstant(v)
|
||||
} else {
|
||||
for _, n := range l.items {
|
||||
c.Compile(n)
|
||||
err := c.Compile(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
c.add(InstructionFormList)
|
||||
c.addU16(uint16(len(l.items)))
|
||||
|
|
@ -102,7 +105,10 @@ func (c *Compiler) Compile(tree Node) error {
|
|||
c.getVar(tree.(*ReferenceNode).name)
|
||||
|
||||
case BinaryNodeType:
|
||||
c.compileBinary(tree.(*BinaryNode))
|
||||
err := c.compileBinary(tree.(*BinaryNode))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case BooleanNodeType:
|
||||
if tree.(*BooleanNode).value {
|
||||
|
|
@ -117,7 +123,10 @@ func (c *Compiler) Compile(tree Node) error {
|
|||
case BlockNodeType:
|
||||
c.descend()
|
||||
for _, n := range tree.(*BlockNode).statements {
|
||||
c.Compile(n)
|
||||
err := c.Compile(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
c.ascend()
|
||||
|
||||
|
|
@ -125,7 +134,10 @@ func (c *Compiler) Compile(tree Node) error {
|
|||
n := tree.(*ConditionalNode)
|
||||
|
||||
// the stack should have whether the condition was truthful
|
||||
c.Compile(n.condition)
|
||||
err := c.Compile(n.condition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if the condition equated to true, we should jump over the body
|
||||
c.add(InstructionJumpFalse)
|
||||
|
|
@ -135,7 +147,10 @@ func (c *Compiler) Compile(tree Node) error {
|
|||
c.advance(2)
|
||||
|
||||
// this part would be executed if the value was true
|
||||
c.Compile(n.do)
|
||||
err = c.Compile(n.do)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// we store the position of the jump over the else code here
|
||||
var jumpOverElse Pos
|
||||
|
|
@ -150,7 +165,10 @@ func (c *Compiler) Compile(tree Node) error {
|
|||
c.putU16(jumpByPos, uint16(c.ip-jumpByPos-2))
|
||||
|
||||
if n.otherwise != nil {
|
||||
c.Compile(n.otherwise)
|
||||
err := c.Compile(n.otherwise)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.putU16(jumpOverElse, uint16(c.ip-jumpOverElse-2))
|
||||
}
|
||||
|
||||
|
|
@ -158,13 +176,19 @@ func (c *Compiler) Compile(tree Node) error {
|
|||
n := tree.(*LoopNode)
|
||||
|
||||
conditionPos := c.ip
|
||||
c.Compile(n.condition)
|
||||
err := c.Compile(n.condition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.add(InstructionJumpFalse)
|
||||
jumpValuePos := c.ip
|
||||
c.advance(2)
|
||||
|
||||
c.Compile(n.do)
|
||||
err = c.Compile(n.do)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.add(InstructionLoop)
|
||||
// condition pos < ip
|
||||
|
|
@ -177,20 +201,32 @@ func (c *Compiler) Compile(tree Node) error {
|
|||
|
||||
if n.name == "_" {
|
||||
// allow non-ish statements
|
||||
c.Compile(n.value)
|
||||
err := c.Compile(n.value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.add(InstructionPop)
|
||||
} else {
|
||||
c.setVar(n.name, n.value, n.declare)
|
||||
err := c.setVar(n.name, n.value, n.declare)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case CallNodeType:
|
||||
n := tree.(*CallNode)
|
||||
|
||||
for _, arg := range n.args {
|
||||
c.Compile(arg)
|
||||
err := c.Compile(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
c.Compile(n.source)
|
||||
err := c.Compile(n.source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.add(InstructionCall)
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ func GetCompileTestData() map[string]CompileTestData {
|
|||
},
|
||||
},
|
||||
},
|
||||
"conditional_welse_false": {
|
||||
"conditional_else_false": {
|
||||
&BlockNode{
|
||||
[]Node{
|
||||
&AssignNode{
|
||||
|
|
@ -164,7 +164,7 @@ func GetCompileTestData() map[string]CompileTestData {
|
|||
},
|
||||
},
|
||||
},
|
||||
"conditional_welse_true": {
|
||||
"conditional_else_true": {
|
||||
&BlockNode{
|
||||
[]Node{
|
||||
&AssignNode{
|
||||
|
|
@ -363,7 +363,10 @@ func TestCompile(t *testing.T) {
|
|||
c := NewCompiler()
|
||||
|
||||
t.Log("Compiling node tree")
|
||||
c.Compile(testCase.tree)
|
||||
err := c.Compile(testCase.tree)
|
||||
if err != nil {
|
||||
t.Fatalf("Compiling failed: %v", err)
|
||||
}
|
||||
|
||||
t.Log("Initializing vm")
|
||||
vm := NewVM(c.Chunk, 256, 256)
|
||||
|
|
@ -387,7 +390,7 @@ func BenchmarkCompile(b *testing.B) {
|
|||
b.Run(name, func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
c := NewCompiler()
|
||||
c.Compile(testCase.tree)
|
||||
_ = c.Compile(testCase.tree)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -426,16 +429,15 @@ func TestCompiler_CleanStack(t *testing.T) {
|
|||
}
|
||||
|
||||
// clean statements
|
||||
case BlockNodeType:
|
||||
case ConditionalNodeType:
|
||||
case LoopNodeType:
|
||||
case AssignNodeType:
|
||||
case FunctionNodeType:
|
||||
default:
|
||||
}
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
c := NewCompiler()
|
||||
c.Compile(tc.tree)
|
||||
err := c.Compile(tc.tree)
|
||||
if err != nil {
|
||||
t.Fatalf("Compiling failed: %v", err)
|
||||
}
|
||||
|
||||
vm := NewVM(c.Chunk, 256, 256)
|
||||
for vm.Next() {
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ func (l *Lexer) NextToken() (Token, error) {
|
|||
|
||||
l.start = l.current
|
||||
|
||||
var c = []rune(l.src)[l.current]
|
||||
var c = l.src[l.current]
|
||||
l.advance()
|
||||
|
||||
switch c {
|
||||
|
|
|
|||
|
|
@ -182,14 +182,14 @@ func TestNewLexer(t *testing.T) {
|
|||
|
||||
// lexer NextToken provides an error when it comes across an invalid token
|
||||
func TestLexer_NextTokenErrors(t *testing.T) {
|
||||
invalid_codes := []string{
|
||||
invalidCodes := []string{
|
||||
// Invalid tokens
|
||||
"^", "@", "$&", "¨",
|
||||
// Non-ending string (in same line)
|
||||
"\"", "Hini minit \"mini moe", "\"this is some test\ncontent\"", "\n\"Hello world",
|
||||
}
|
||||
|
||||
for _, code := range invalid_codes {
|
||||
for _, code := range invalidCodes {
|
||||
lex := NewLexer(code)
|
||||
tok, err := lex.NextToken()
|
||||
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ func (n NilNode) String() string {
|
|||
return "nil"
|
||||
}
|
||||
|
||||
// block node with statements
|
||||
// BlockNode block node with statements
|
||||
type BlockNode struct {
|
||||
statements []Node
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ func (n ConditionalNode) String() string {
|
|||
return fmt.Sprintf("if %s then %s otheriwise %s", n.condition.String(), n.do.String(), n.otherwise.String())
|
||||
}
|
||||
|
||||
// Loops (for/while)
|
||||
// LoopNode Loops (for/while)
|
||||
type LoopNode struct {
|
||||
condition Node
|
||||
do Node
|
||||
|
|
@ -298,7 +298,7 @@ func (n LoopNode) String() string {
|
|||
return fmt.Sprintf("while %s loop %s", n.condition.String(), n.do.String())
|
||||
}
|
||||
|
||||
// assignment
|
||||
// AssignNode assignment
|
||||
type AssignNode struct {
|
||||
name string
|
||||
value Node
|
||||
|
|
@ -313,7 +313,7 @@ func (n AssignNode) String() string {
|
|||
return fmt.Sprintf("set %s to %s", n.name, n.value)
|
||||
}
|
||||
|
||||
// function call
|
||||
// CallNode function call
|
||||
type CallNode struct {
|
||||
source Node
|
||||
args []Node
|
||||
|
|
@ -328,7 +328,7 @@ func (n CallNode) String() string {
|
|||
return fmt.Sprintf("call %s with args (%s)", n.source.String(), n.args)
|
||||
}
|
||||
|
||||
// definition of function
|
||||
// FunctionNode definition of function
|
||||
type FunctionNode struct {
|
||||
name string
|
||||
params []string
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ func (p *ParsingError) Error() string {
|
|||
return p.Description
|
||||
}
|
||||
|
||||
// Print a rich and informative error
|
||||
// Format Print a rich and informative error
|
||||
func (p *ParsingError) Format(src []rune) string {
|
||||
builder := strings.Builder{}
|
||||
|
||||
|
|
|
|||
|
|
@ -667,9 +667,9 @@ func NodeEquality(t *testing.T, n1 Node, n2 Node) {
|
|||
|
||||
func TestParser_Parse(t *testing.T) {
|
||||
t.Logf("Getting test data")
|
||||
token_data := GetTokenTestData()
|
||||
tokenData := GetTokenTestData()
|
||||
|
||||
for name, data := range token_data {
|
||||
for name, data := range tokenData {
|
||||
if name != "empty_block" && name != "lambda" {
|
||||
continue
|
||||
}
|
||||
|
|
@ -692,9 +692,9 @@ func TestParser_Parse(t *testing.T) {
|
|||
}
|
||||
|
||||
func BenchmarkParser_Parse(b *testing.B) {
|
||||
token_data := GetTokenTestData()
|
||||
tokenData := GetTokenTestData()
|
||||
|
||||
for name, data := range token_data {
|
||||
for name, data := range tokenData {
|
||||
b.Run(name, func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
p := NewParser(data.tokens)
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ func (v *BoolValue) Equals(other Value) bool {
|
|||
return other.Type() == BoolValueType && other.(*BoolValue).bool == v.bool
|
||||
}
|
||||
|
||||
func (v *BoolValue) Get(key string) (Value, error) {
|
||||
func (v *BoolValue) Get(_ string) (Value, error) {
|
||||
return nil, errors.New("booleans have no properties")
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ func (v *NumberValue) Equals(other Value) bool {
|
|||
return other.Type() == NumberValueType && other.(*NumberValue).float64 == v.float64
|
||||
}
|
||||
|
||||
func (v *NumberValue) Get(key string) (Value, error) {
|
||||
func (v *NumberValue) Get(_ string) (Value, error) {
|
||||
// TODO maybe add standard functions for number values?
|
||||
return nil, errors.New("numbers have no properties")
|
||||
}
|
||||
|
|
@ -489,7 +489,7 @@ type BuiltinFunctionValue struct {
|
|||
Parent Value
|
||||
}
|
||||
|
||||
func (v BuiltinFunctionValue) Type() ValueType {
|
||||
func (v *BuiltinFunctionValue) Type() ValueType {
|
||||
return BuiltinFunctionValueType
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue