mirror of
https://github.com/hazemKrimi/jack-compiler.git
synced 2026-05-01 17:48:57 +00:00
feat: compile second test program
This commit is contained in:
@@ -64,7 +64,7 @@ func compileTerm(output *strings.Builder, tokens []tokenizer.Token, index *int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tokens[*index].Value == "this" {
|
if tokens[*index].Value == "this" {
|
||||||
variable, found := table.GetVariable([]*map[string]table.Variable{&subroutineSymbolTable, &classSymbolTable}, tokens[*index].Value)
|
variable, found := table.GetVariable([]*map[string]table.Variable{&subroutineSymbolTable}, tokens[*index].Value)
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
return errors.New("Invalid identifier!")
|
return errors.New("Invalid identifier!")
|
||||||
@@ -110,12 +110,14 @@ func compileTerm(output *strings.Builder, tokens []tokenizer.Token, index *int)
|
|||||||
return errors.New("Invalid identifier!")
|
return errors.New("Invalid identifier!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var identifier string
|
||||||
|
|
||||||
if found {
|
if found {
|
||||||
code.WritePush(output, segmentFromVariableKind(variable.Kind), variable.Count)
|
code.WritePush(output, segmentFromVariableKind(variable.Kind), variable.Count)
|
||||||
|
} else {
|
||||||
|
identifier = tokens[*index].Value
|
||||||
}
|
}
|
||||||
|
|
||||||
identifier := tokens[*index].Value
|
|
||||||
|
|
||||||
(*index)++
|
(*index)++
|
||||||
|
|
||||||
if tokens[*index].Value == "[" {
|
if tokens[*index].Value == "[" {
|
||||||
@@ -281,20 +283,9 @@ func compileSubroutineCall(output *strings.Builder, tokens []tokenizer.Token, in
|
|||||||
var class string
|
var class string
|
||||||
var function string
|
var function string
|
||||||
|
|
||||||
isMethod := false
|
|
||||||
|
|
||||||
if tokens[*index].Value == "." {
|
if tokens[*index].Value == "." {
|
||||||
variable, found := table.GetVariable([]*map[string]table.Variable{&subroutineSymbolTable, &classSymbolTable}, identifier)
|
|
||||||
|
|
||||||
if found {
|
|
||||||
code.WritePush(output, segmentFromVariableKind(variable.Kind), variable.Count)
|
|
||||||
code.WritePop(output, code.ARGUMENT, 0)
|
|
||||||
|
|
||||||
isMethod = true
|
|
||||||
class = variable.Type
|
|
||||||
} else {
|
|
||||||
class = identifier
|
class = identifier
|
||||||
}
|
|
||||||
|
|
||||||
(*index)++
|
(*index)++
|
||||||
|
|
||||||
@@ -323,10 +314,6 @@ func compileSubroutineCall(output *strings.Builder, tokens []tokenizer.Token, in
|
|||||||
return errors.New("Missing subroutine call closing parenthese!")
|
return errors.New("Missing subroutine call closing parenthese!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if isMethod {
|
|
||||||
args++
|
|
||||||
}
|
|
||||||
|
|
||||||
code.WriteCall(output, function, args)
|
code.WriteCall(output, function, args)
|
||||||
|
|
||||||
(*index)++
|
(*index)++
|
||||||
@@ -388,6 +375,11 @@ func compileLetStatement(output *strings.Builder, tokens []tokenizer.Token, inde
|
|||||||
}
|
}
|
||||||
|
|
||||||
func compileIfStatement(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
|
func compileIfStatement(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
|
||||||
|
endLabel := "IF_END_" + fmt.Sprint(ifLabelIndex)
|
||||||
|
elseLabel := "IF_ELSE_" + fmt.Sprint(ifLabelIndex)
|
||||||
|
|
||||||
|
ifLabelIndex++
|
||||||
|
|
||||||
if tokens[*index].Type != tokenizer.KEYWORD || tokens[*index].Value != "if" {
|
if tokens[*index].Type != tokenizer.KEYWORD || tokens[*index].Value != "if" {
|
||||||
return errors.New("Invalid if statement!")
|
return errors.New("Invalid if statement!")
|
||||||
}
|
}
|
||||||
@@ -405,7 +397,7 @@ func compileIfStatement(output *strings.Builder, tokens []tokenizer.Token, index
|
|||||||
}
|
}
|
||||||
|
|
||||||
code.WriteArithmeticLogical(output, code.NOT)
|
code.WriteArithmeticLogical(output, code.NOT)
|
||||||
code.WriteIfGoto(output, "IF_ELSE_"+fmt.Sprint(ifLabelIndex))
|
code.WriteIfGoto(output, elseLabel)
|
||||||
|
|
||||||
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != ")" {
|
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != ")" {
|
||||||
return errors.New("Missing if statement closing parenthese!")
|
return errors.New("Missing if statement closing parenthese!")
|
||||||
@@ -423,7 +415,7 @@ func compileIfStatement(output *strings.Builder, tokens []tokenizer.Token, index
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
code.WriteGoto(output, "IF_END_"+fmt.Sprint(ifLabelIndex))
|
code.WriteGoto(output, endLabel)
|
||||||
|
|
||||||
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "}" {
|
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "}" {
|
||||||
return errors.New("Missing if statement closing curly brace!")
|
return errors.New("Missing if statement closing curly brace!")
|
||||||
@@ -440,7 +432,7 @@ func compileIfStatement(output *strings.Builder, tokens []tokenizer.Token, index
|
|||||||
|
|
||||||
(*index)++
|
(*index)++
|
||||||
|
|
||||||
code.WriteLabel(output, "IF_ELSE_"+fmt.Sprint(ifLabelIndex))
|
code.WriteLabel(output, elseLabel)
|
||||||
|
|
||||||
if err := compileStatements(output, tokens, index); err != nil {
|
if err := compileStatements(output, tokens, index); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -453,13 +445,17 @@ func compileIfStatement(output *strings.Builder, tokens []tokenizer.Token, index
|
|||||||
(*index)++
|
(*index)++
|
||||||
}
|
}
|
||||||
|
|
||||||
code.WriteLabel(output, "IF_END_"+fmt.Sprint(ifLabelIndex))
|
code.WriteLabel(output, endLabel)
|
||||||
ifLabelIndex++
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileWhileStatement(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
|
func compileWhileStatement(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
|
||||||
|
startLabel := "WHILE_START_"+fmt.Sprint(whileLabelIndex)
|
||||||
|
endLabel := "WHILE_END_"+fmt.Sprint(whileLabelIndex)
|
||||||
|
|
||||||
|
whileLabelIndex++
|
||||||
|
|
||||||
if tokens[*index].Type != tokenizer.KEYWORD || tokens[*index].Value != "while" {
|
if tokens[*index].Type != tokenizer.KEYWORD || tokens[*index].Value != "while" {
|
||||||
return errors.New("Invalid while statement!")
|
return errors.New("Invalid while statement!")
|
||||||
}
|
}
|
||||||
@@ -472,14 +468,14 @@ func compileWhileStatement(output *strings.Builder, tokens []tokenizer.Token, in
|
|||||||
|
|
||||||
(*index)++
|
(*index)++
|
||||||
|
|
||||||
code.WriteLabel(output, "WHILE_START_"+fmt.Sprint(whileLabelIndex))
|
code.WriteLabel(output, startLabel)
|
||||||
|
|
||||||
if err := compileExpression(output, tokens, index); err != nil {
|
if err := compileExpression(output, tokens, index); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
code.WriteArithmeticLogical(output, code.NOT)
|
code.WriteArithmeticLogical(output, code.NOT)
|
||||||
code.WriteIfGoto(output, "WHILE_END_"+fmt.Sprint(whileLabelIndex))
|
code.WriteIfGoto(output, endLabel)
|
||||||
|
|
||||||
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != ")" {
|
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != ")" {
|
||||||
return errors.New("Missing while statement closing parenthese!")
|
return errors.New("Missing while statement closing parenthese!")
|
||||||
@@ -497,14 +493,14 @@ func compileWhileStatement(output *strings.Builder, tokens []tokenizer.Token, in
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
code.WriteGoto(output, "WHILE_START_"+fmt.Sprint(whileLabelIndex))
|
code.WriteGoto(output, startLabel)
|
||||||
|
|
||||||
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "}" {
|
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "}" {
|
||||||
return errors.New("Missing while statement closing curly brace!")
|
return errors.New("Missing while statement closing curly brace!")
|
||||||
}
|
}
|
||||||
|
|
||||||
code.WriteLabel(output, "WHILE_END_"+fmt.Sprint(whileLabelIndex))
|
code.WriteLabel(output, endLabel)
|
||||||
whileLabelIndex++
|
|
||||||
(*index)++
|
(*index)++
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user