diff --git a/internal/compilation-engine/compilation-engine.go b/internal/compilation-engine/compilation-engine.go index 60d7ad7..0692355 100644 --- a/internal/compilation-engine/compilation-engine.go +++ b/internal/compilation-engine/compilation-engine.go @@ -51,12 +51,15 @@ func compileClassVarDec(output *strings.Builder, tokens []tokenizer.Token, index return errors.New("Missing semicolon!") } + output.WriteString(" " + tokens[*index].Value + " \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("\n") + output.WriteString("\n") output.WriteString(" " + tokens[*index].Value + " \n") + output.WriteString("\n") + output.WriteString("\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(" " + tokens[*index].Value + " \n") + *(index)++ + + if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "(" { + return errors.New("Missing if statement opening parenthese!") + } + + output.WriteString(" " + tokens[*index].Value + " \n") + *(index)++ + + // TODO: Change to expression compilation + if tokens[*index].Type != tokenizer.IDENTIFIER { + return errors.New("Invalid variable name!") + } + + output.WriteString("\n") + output.WriteString("\n") + output.WriteString(" " + tokens[*index].Value + " \n") + output.WriteString("\n") + output.WriteString("\n") + *(index)++ + + if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != ")" { + return errors.New("Missing if statement closing parenthese!") + } + + output.WriteString(" " + tokens[*index].Value + " \n") + *(index)++ + + if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "{" { + return errors.New("Missing if statement opening curly brace!") + } + + output.WriteString(" " + tokens[*index].Value + " \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(" " + tokens[*index].Value + " \n") + *(index)++ + + if tokens[*index].Type == tokenizer.KEYWORD || tokens[*index].Value == "else" { + output.WriteString(" " + tokens[*index].Value + " \n") + *(index)++ + + if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "{" { + return errors.New("Missing if statement opening curly brace!") + } + + output.WriteString(" " + tokens[*index].Value + " \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(" " + tokens[*index].Value + " \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(" " + tokens[*index].Value + " \n") + *(index)++ + + if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "(" { + return errors.New("Missing while statement opening parenthese!") + } + + output.WriteString(" " + tokens[*index].Value + " \n") + *(index)++ + + // TODO: Change to expression compilation + if tokens[*index].Type != tokenizer.IDENTIFIER { + return errors.New("Invalid variable name!") + } + + output.WriteString("\n") + output.WriteString("\n") + output.WriteString(" " + tokens[*index].Value + " \n") + output.WriteString("\n") + output.WriteString("\n") + *(index)++ + + if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != ")" { + return errors.New("Missing while statement closing parenthese!") + } + + output.WriteString(" " + tokens[*index].Value + " \n") + *(index)++ + + if tokens[*index].Type != tokenizer.SYMBOL || tokens[*index].Value != "{" { + return errors.New("Missing while statement opening curly brace!") + } + + output.WriteString(" " + tokens[*index].Value + " \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(" " + tokens[*index].Value + " \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(" " + tokens[*index].Value + " \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("\n") + output.WriteString("\n") output.WriteString(" " + tokens[*index].Value + " \n") + output.WriteString("\n") + output.WriteString("\n") *(index)++ } @@ -406,37 +542,37 @@ func ParseTokens(tokens []tokenizer.Token) (string, error) { return "", err } - output.WriteString("\n") + // output.WriteString("\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 = "<" + // case ">": + // value = ">" + // case "&": + // value = "&" + // default: + // value = token.Value + // } + // + // output.WriteString(" " + value + " \n") + // case tokenizer.KEYWORD: + // output.WriteString(" " + token.Value + " \n") + // case tokenizer.IDENTIFIER: + // output.WriteString(" " + token.Value + " \n") + // case tokenizer.INT_CONST: + // output.WriteString(" " + token.Value + " \n") + // case tokenizer.STR_CONST: + // output.WriteString(" " + token.Value + " \n") + // } + // } - switch token.Value { - case "<": - value = "<" - case ">": - value = ">" - case "&": - value = "&" - default: - value = token.Value - } - - output.WriteString(" " + value + " \n") - case tokenizer.KEYWORD: - output.WriteString(" " + token.Value + " \n") - case tokenizer.IDENTIFIER: - output.WriteString(" " + token.Value + " \n") - case tokenizer.INT_CONST: - output.WriteString(" " + token.Value + " \n") - case tokenizer.STR_CONST: - output.WriteString(" " + token.Value + " \n") - } - } - - output.WriteString("\n") + // output.WriteString("\n") return output.String(), nil }