mirror of
https://github.com/hazemKrimi/jack-compiler.git
synced 2026-05-01 17:48:57 +00:00
feat: handle string literals and array access and assignment
This commit is contained in:
@@ -73,6 +73,16 @@ func compileTerm(output *strings.Builder, tokens []tokenizer.Token, index *int)
|
||||
code.WritePush(output, code.CONSTANT, int(number))
|
||||
}
|
||||
|
||||
if tokens[*index].Type == tokenizer.STR_CONST {
|
||||
code.WritePush(output, code.CONSTANT, len(tokens[*index].Value))
|
||||
code.WriteCall(output, "String.new", 1)
|
||||
|
||||
for _, char := range tokens[*index].Value {
|
||||
code.WritePush(output, code.CONSTANT, int(char))
|
||||
code.WriteCall(output, "String.appendChar", 2)
|
||||
}
|
||||
}
|
||||
|
||||
if tokens[*index].Value == "this" {
|
||||
variable, found := table.GetVariable([]*map[string]table.Variable{&subroutineSymbolTable}, tokens[*index].Value)
|
||||
|
||||
@@ -141,6 +151,10 @@ func compileTerm(output *strings.Builder, tokens []tokenizer.Token, index *int)
|
||||
return errors.New("Invalid term!")
|
||||
}
|
||||
|
||||
code.WriteArithmeticLogical(output, code.ADD)
|
||||
code.WritePop(output, code.POINTER, 1)
|
||||
code.WritePush(output, code.THAT, 0)
|
||||
|
||||
(*index)++
|
||||
} else if slices.Contains([]string{"(", "."}, tokens[*index].Value) {
|
||||
if err := compileSubroutineCall(output, tokens, index, identifier); err != nil {
|
||||
@@ -359,6 +373,8 @@ func compileSubroutineCall(output *strings.Builder, tokens []tokenizer.Token, in
|
||||
}
|
||||
|
||||
func compileLetStatement(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
|
||||
var isArrayAccess bool
|
||||
|
||||
if tokens[*index].Type != tokenizer.KEYWORD || tokens[*index].Value != "let" {
|
||||
return errors.New("Invalid let statement!")
|
||||
}
|
||||
@@ -378,6 +394,10 @@ func compileLetStatement(output *strings.Builder, tokens []tokenizer.Token, inde
|
||||
(*index)++
|
||||
|
||||
if tokens[*index].Value == "[" {
|
||||
isArrayAccess = true
|
||||
|
||||
code.WritePush(output, segmentFromVariableKind(variable.Kind), variable.Count)
|
||||
|
||||
(*index)++
|
||||
|
||||
if err := compileExpression(output, tokens, index); err != nil {
|
||||
@@ -388,6 +408,8 @@ func compileLetStatement(output *strings.Builder, tokens []tokenizer.Token, inde
|
||||
return errors.New("Invalid expression!")
|
||||
}
|
||||
|
||||
code.WriteArithmeticLogical(output, code.ADD)
|
||||
|
||||
(*index)++
|
||||
}
|
||||
|
||||
@@ -405,7 +427,15 @@ func compileLetStatement(output *strings.Builder, tokens []tokenizer.Token, inde
|
||||
return errors.New("Missing semicolon!")
|
||||
}
|
||||
|
||||
code.WritePop(output, segmentFromVariableKind(variable.Kind), variable.Count)
|
||||
if isArrayAccess {
|
||||
code.WritePop(output, code.TEMP, 0)
|
||||
code.WritePop(output, code.POINTER, 1)
|
||||
code.WritePush(output, code.TEMP, 0)
|
||||
code.WritePop(output, code.THAT, 0)
|
||||
} else {
|
||||
code.WritePop(output, segmentFromVariableKind(variable.Kind), variable.Count)
|
||||
}
|
||||
|
||||
(*index)++
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user