chore: finish compilation engine scaffolding with some fixes

This commit is contained in:
2026-04-21 14:12:09 +01:00
parent ba853b24b1
commit 6d23e64f80
+167 -31
View File
@@ -51,12 +51,15 @@ func compileClassVarDec(output *strings.Builder, tokens []tokenizer.Token, index
return errors.New("Missing semicolon!")
}
output.WriteString("<identifier> " + tokens[*index].Value + " </identifier>\n")
(*index)++
return compileClassVarDec(output, tokens, index)
}
func compileParameterList(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
if !slices.Contains([]tokenizer.TokenType{tokenizer.KEYWORD, tokenizer.IDENTIFIER}, tokens[*index].Type) || !slices.Contains([]string{"int", "char", "boolean"}, tokens[*index].Value) {
return errors.New("Invalid variable type name!")
return nil
}
if tokens[*index].Type == tokenizer.KEYWORD {
@@ -142,7 +145,11 @@ func compileLetStatement(output *strings.Builder, tokens []tokenizer.Token, inde
return errors.New("Invalid variable name!")
}
output.WriteString("<expression>\n")
output.WriteString("<term>\n")
output.WriteString("<identifier> " + tokens[*index].Value + " </identifier>\n")
output.WriteString("</term>\n")
output.WriteString("</expression>\n")
*(index)++
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "=" {
@@ -171,16 +178,141 @@ func compileLetStatement(output *strings.Builder, tokens []tokenizer.Token, inde
}
func compileIfStatement(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
if tokens[*index].Type != tokenizer.KEYWORD || tokens[*index].Value != "if" {
return errors.New("Invalid if statement!")
}
output.WriteString("<keyword> " + tokens[*index].Value + " </keyword>\n")
*(index)++
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "(" {
return errors.New("Missing if statement opening parenthese!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
// TODO: Change to expression compilation
if tokens[*index].Type != tokenizer.IDENTIFIER {
return errors.New("Invalid variable name!")
}
output.WriteString("<expression>\n")
output.WriteString("<term>\n")
output.WriteString("<identifier> " + tokens[*index].Value + " </identifier>\n")
output.WriteString("</term>\n")
output.WriteString("</expression>\n")
*(index)++
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != ")" {
return errors.New("Missing if statement closing parenthese!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "{" {
return errors.New("Missing if statement opening curly brace!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
if err := compileStatements(output, tokens, index); err != nil {
return err
}
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "}" {
return errors.New("Missing if statement closing curly brace!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
if tokens[*index].Type == tokenizer.KEYWORD || tokens[*index].Value == "else" {
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "{" {
return errors.New("Missing if statement opening curly brace!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
if err := compileStatements(output, tokens, index); err != nil {
return err
}
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "}" {
return errors.New("Missing if statement closing curly brace!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
}
return nil
}
func compileWhileStatement(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
if tokens[*index].Type != tokenizer.KEYWORD || tokens[*index].Value != "while" {
return errors.New("Invalid while statement!")
}
output.WriteString("<keyword> " + tokens[*index].Value + " </keyword>\n")
*(index)++
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "(" {
return errors.New("Missing while statement opening parenthese!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
// TODO: Change to expression compilation
if tokens[*index].Type != tokenizer.IDENTIFIER {
return errors.New("Invalid variable name!")
}
output.WriteString("<expression>\n")
output.WriteString("<term>\n")
output.WriteString("<identifier> " + tokens[*index].Value + " </identifier>\n")
output.WriteString("</term>\n")
output.WriteString("</expression>\n")
*(index)++
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != ")" {
return errors.New("Missing while statement closing parenthese!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "{" {
return errors.New("Missing while statement opening curly brace!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
if err := compileStatements(output, tokens, index); err != nil {
return err
}
if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "}" {
return errors.New("Missing while statement closing curly brace!")
}
output.WriteString("<symbol> " + tokens[*index].Value + " </symbol>\n")
*(index)++
return nil
}
func compileDoStatement(output *strings.Builder, tokens []tokenizer.Token, index *int) error {
if tokens[*index].Type != tokenizer.KEYWORD || tokens[*index].Value != "do" {
return errors.New("Invalid return statement!")
return errors.New("Invalid do statement!")
}
output.WriteString("<keyword> " + tokens[*index].Value + " </keyword>\n")
@@ -199,7 +331,11 @@ func compileReturnStatement(output *strings.Builder, tokens []tokenizer.Token, i
// TODO: Change to expression compilation
if tokens[*index].Type == tokenizer.IDENTIFIER {
output.WriteString("<expression>\n")
output.WriteString("<term>\n")
output.WriteString("<identifier> " + tokens[*index].Value + " </identifier>\n")
output.WriteString("</term>\n")
output.WriteString("</expression>\n")
*(index)++
}
@@ -406,37 +542,37 @@ func ParseTokens(tokens []tokenizer.Token) (string, error) {
return "", err
}
output.WriteString("<tokens>\n")
// output.WriteString("<tokens>\n")
for _, token := range tokens {
switch token.Type {
case tokenizer.SYMBOL:
var value string
// for _, token := range tokens {
// switch token.Type {
// case tokenizer.SYMBOL:
// var value string
//
// switch token.Value {
// case "<":
// value = "&lt;"
// case ">":
// value = "&gt;"
// case "&":
// value = "&amp;"
// default:
// value = token.Value
// }
//
// output.WriteString("<symbol> " + value + " </symbol>\n")
// case tokenizer.KEYWORD:
// output.WriteString("<keyword> " + token.Value + " </keyword>\n")
// case tokenizer.IDENTIFIER:
// output.WriteString("<identifier> " + token.Value + " </identifier>\n")
// case tokenizer.INT_CONST:
// output.WriteString("<integerConstant> " + token.Value + " </integerConstant>\n")
// case tokenizer.STR_CONST:
// output.WriteString("<stringConstant> " + token.Value + " </stringConstant>\n")
// }
// }
switch token.Value {
case "<":
value = "&lt;"
case ">":
value = "&gt;"
case "&":
value = "&amp;"
default:
value = token.Value
}
output.WriteString("<symbol> " + value + " </symbol>\n")
case tokenizer.KEYWORD:
output.WriteString("<keyword> " + token.Value + " </keyword>\n")
case tokenizer.IDENTIFIER:
output.WriteString("<identifier> " + token.Value + " </identifier>\n")
case tokenizer.INT_CONST:
output.WriteString("<integerConstant> " + token.Value + " </integerConstant>\n")
case tokenizer.STR_CONST:
output.WriteString("<stringConstant> " + token.Value + " </stringConstant>\n")
}
}
output.WriteString("</tokens>\n")
// output.WriteString("</tokens>\n")
return output.String(), nil
}