diff options
| author | AidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com> | 2021-11-27 19:37:41 +0000 | 
|---|---|---|
| committer | AidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com> | 2021-11-27 19:37:41 +0000 | 
| commit | 8badb0fab61a23dd81466c3f5f8aadd77bf952e3 (patch) | |
| tree | 41a7e51e700ddee1a4e66aebfd3edaea29b60203 /src/Compiler | |
| parent | ac425713cfd5a4fac7ce5b607d722eeb9954ba10 (diff) | |
| download | esotericFORTRAN-8badb0fab61a23dd81466c3f5f8aadd77bf952e3.tar.gz esotericFORTRAN-8badb0fab61a23dd81466c3f5f8aadd77bf952e3.zip | |
Added basic support for arrays
Diffstat (limited to 'src/Compiler')
| -rw-r--r-- | src/Compiler/Expression.java | 27 | ||||
| -rw-r--r-- | src/Compiler/Parser.java | 52 | ||||
| -rw-r--r-- | src/Compiler/Statement.java | 32 | ||||
| -rw-r--r-- | src/Compiler/TokenScanner.java | 1 | ||||
| -rw-r--r-- | src/Compiler/TokenType.java | 2 | ||||
| -rw-r--r-- | src/Compiler/Translator.java | 57 | 
6 files changed, 142 insertions, 29 deletions
| diff --git a/src/Compiler/Expression.java b/src/Compiler/Expression.java index d331f24..8bdf378 100644 --- a/src/Compiler/Expression.java +++ b/src/Compiler/Expression.java @@ -1,5 +1,7 @@  package Compiler; +import java.util.List; +  abstract class Expression {      static class Binary extends Expression{ @@ -70,11 +72,11 @@ abstract class Expression {      }      static class AssignmentExpression extends Expression{ -        final Token name; +        final Expression variable;          final Expression value; -        AssignmentExpression(Token name,Expression value){ -            this.name=name; +        AssignmentExpression(Expression variable,Expression value){ +            this.variable=variable;              this.value=value;          } @@ -82,8 +84,7 @@ abstract class Expression {          @Override          public String getExpressionType() {              return "assign"; -        } -         +        }         }      static class Variable extends Expression{ @@ -99,5 +100,21 @@ abstract class Expression {          final Token name;      } + +    static class ArrayVariable extends Expression{ +         +        ArrayVariable(Token name,List<Expression> positions){ +            this.name=name; +            this.positions=positions; + +        } +        @Override +        public String getExpressionType() { +            return "arrayvar"; +        } +        final Token name; +        final List<Expression> positions; +         +    }      public abstract String getExpressionType();  } diff --git a/src/Compiler/Parser.java b/src/Compiler/Parser.java index d0556e4..eba3513 100644 --- a/src/Compiler/Parser.java +++ b/src/Compiler/Parser.java @@ -3,7 +3,6 @@ package Compiler;  import java.util.ArrayList;  import java.util.List; -import Compiler.Statement.BlockStatement;  public class Parser {      private final List<Token> tokens; @@ -44,11 +43,17 @@ public class Parser {      //Clean up and reduce code mess      private Statement declaration(){          if (matchAndAdvance(TokenType.INT)){ +            if(matchAndAdvance(TokenType.DIMENSION)){ +                return arrayDeclaration("int"); +            }              matchOrError(TokenType.DEFINE, ":: Required for variable definition");              matchOrError(TokenType.IDENTIFIER,"Expected variable name.");              Token varName = getPreviousToken();              return new Statement.VariableDeclaration(varName,"int");          } else if (matchAndAdvance(TokenType.REAL)){ +            if(matchAndAdvance(TokenType.DIMENSION)){ +                return arrayDeclaration("real"); +            }              matchOrError(TokenType.DEFINE, ":: Required for variable definition");              matchOrError(TokenType.IDENTIFIER,"Expected variable name.");              Token varName = getPreviousToken(); @@ -79,7 +84,23 @@ public class Parser {          return null;      } -    private BlockStatement blockStatement(){ +    private Statement arrayDeclaration(String type){ +        matchOrError(TokenType.LEFT_PAREN,"Expected ')'"); +        List<Expression> dimensions = new ArrayList<>(); +        Expression dimension = expression(); +        dimensions.add(dimension); +        while(matchAndAdvance(TokenType.COMMA)){ +            dimension = expression(); +            dimensions.add(dimension); +        } +        matchOrError(TokenType.RIGHT_PAREN, "Expected ')'"); +        matchOrError(TokenType.DEFINE, ":: Required for variable definition"); +        matchOrError(TokenType.IDENTIFIER,"Expected variable name."); +        Token varName = getPreviousToken(); +        return new Statement.ArrayDeclaration(varName, type, dimensions); +    } + +    private Statement blockStatement(){          List<Statement> statements = new ArrayList<>();          while(!matchAndAdvance(TokenType.END)&&!checkToken(TokenType.ELSE)){              if(checkEOF()){ @@ -107,8 +128,8 @@ public class Parser {      private Statement ifStatement(){          Expression condition = expression();          if(matchOrError(TokenType.THEN, "then expected after if statement")){ -            Statement.BlockStatement ifBlock = blockStatement(); -            Statement.BlockStatement elseBlock=null; +            Statement ifBlock = blockStatement(); +            Statement elseBlock=null;              if(matchAndAdvance(TokenType.ELSE)){                  elseBlock=blockStatement(); @@ -133,7 +154,7 @@ public class Parser {          if(matchAndAdvance(TokenType.COMMA)){             step = expression();          } -        Statement.BlockStatement codeBlock = blockStatement(); +        Statement codeBlock = blockStatement();          matchOrError(TokenType.DO, "Do statements end with do");          return new Statement.DoStatement(variable, start, stop, step,codeBlock); @@ -143,7 +164,7 @@ public class Parser {          matchOrError(TokenType.LEFT_PAREN, " missing '(' for do statement condition");          Expression condition = expression();          matchOrError(TokenType.RIGHT_PAREN, " missing ')' for do  condition"); -        Statement.BlockStatement codeBlock = blockStatement(); +        Statement codeBlock = blockStatement();          matchOrError(TokenType.DO, "Do while statements end with do");          return new Statement.DoWhileStatement(condition,codeBlock);      } @@ -157,11 +178,7 @@ public class Parser {          Expression variable = expression();          if (matchAndAdvance(TokenType.EQUALS)){              Expression assignedvalue = expression(); - -            if (variable instanceof Expression.Variable){ -                return new Expression.AssignmentExpression(((Expression.Variable)variable).name,assignedvalue); -            } -            throw error(getCurrentToken(),"Left of assignment must be a variable"); +            return new Expression.AssignmentExpression(variable,assignedvalue);          }          return variable;      } @@ -240,7 +257,18 @@ public class Parser {          }          if (matchAndAdvance(TokenType.IDENTIFIER)) { - +            Token name= getPreviousToken(); +            if(matchAndAdvance(TokenType.LEFT_PAREN)){ +                List<Expression> positions = new ArrayList<>(); +                Expression position = expression(); +                positions.add(position); +                while(matchAndAdvance(TokenType.COMMA)){ +                    position = expression(); +                    positions.add(position); +                } +                matchOrError(TokenType.RIGHT_PAREN,"Expected ')'"); +                return new Expression.ArrayVariable(name, positions); +            }              return new Expression.Variable(getPreviousToken());            } diff --git a/src/Compiler/Statement.java b/src/Compiler/Statement.java index a3c0960..a4fbff7 100644 --- a/src/Compiler/Statement.java +++ b/src/Compiler/Statement.java @@ -33,15 +33,15 @@ abstract class Statement {      }      static class IfStatement extends Statement{ -        IfStatement(Expression condition, BlockStatement ifBlock,BlockStatement elseBlock){ +        IfStatement(Expression condition, Statement ifBlock,Statement elseBlock){              this.condition=condition;              this.ifBlock=ifBlock;              this.elseBlock=elseBlock;          }          final Expression condition; -        final BlockStatement ifBlock; -        final BlockStatement elseBlock; +        final Statement ifBlock; +        final Statement elseBlock;          @Override          public String getStatmentType() { @@ -50,7 +50,7 @@ abstract class Statement {      }      static class DoStatement extends Statement{ -        DoStatement(Expression variable, Expression start,Expression stop,Expression step,BlockStatement codeBlock){ +        DoStatement(Expression variable, Expression start,Expression stop,Expression step,Statement codeBlock){              this.variable=variable;              this.start=start;              this.stop=stop; @@ -63,7 +63,7 @@ abstract class Statement {          final Expression start;          final Expression stop;          final Expression step; -        final BlockStatement codeBlock; +        final Statement codeBlock;          @Override          public String getStatmentType() { @@ -72,14 +72,14 @@ abstract class Statement {      }      static class DoWhileStatement extends Statement{ -        DoWhileStatement(Expression condition,BlockStatement codeBlock){ +        DoWhileStatement(Expression condition,Statement codeBlock){              this.condition=condition;              this.codeBlock=codeBlock;          }          final Expression condition; -        final BlockStatement codeBlock; +        final Statement codeBlock;          @Override          public String getStatmentType() { @@ -122,6 +122,24 @@ abstract class Statement {      } +    static class ArrayDeclaration extends Statement{ +        ArrayDeclaration(Token name,String type,List<Expression> dimensions){ +            this.name=name; +            this.dimensions=dimensions; +            this.type=type; +        } + +        final String type; +        final Token name; +        final List<Expression> dimensions; + +        @Override +        public String getStatmentType() { +            return "arrayDec"; +        } + +    } +      static class PrintStatement extends Statement{          PrintStatement(List<Expression> exprList){              this.exprList=exprList; diff --git a/src/Compiler/TokenScanner.java b/src/Compiler/TokenScanner.java index 5f55119..aed5f38 100644 --- a/src/Compiler/TokenScanner.java +++ b/src/Compiler/TokenScanner.java @@ -228,5 +228,6 @@ public class TokenScanner {          keywords.put("else",    TokenType.ELSE);          keywords.put("do",    TokenType.DO);          keywords.put("while",    TokenType.WHILE); +        keywords.put("dimension",    TokenType.DIMENSION);        }  } diff --git a/src/Compiler/TokenType.java b/src/Compiler/TokenType.java index a82d169..bc82cde 100644 --- a/src/Compiler/TokenType.java +++ b/src/Compiler/TokenType.java @@ -12,7 +12,7 @@ public enum TokenType {      NUMBER,IDENTIFIER,STRING, -    INT,REAL,PRINT,ENDPRINT,IF,THEN,END,ELSE,LEN,DO,WHILE,AND,OR,NOT, +    INT,REAL,PRINT,ENDPRINT,IF,THEN,END,ELSE,LEN,DO,WHILE,AND,OR,NOT,DIMENSION,      EOF  } diff --git a/src/Compiler/Translator.java b/src/Compiler/Translator.java index c40c6b5..a79242d 100644 --- a/src/Compiler/Translator.java +++ b/src/Compiler/Translator.java @@ -46,6 +46,9 @@ public class Translator{              case "stringDec":                  evalStringDeclaration((StringDeclaration)statement);                  break; +            case "arrayDec": +                evalArrayDeclaration((ArrayDeclaration)statement); +                break;              case "block":                  evalBlockStatement((BlockStatement)statement);                  break; @@ -83,6 +86,26 @@ public class Translator{          }       } +    private void evalArrayDeclaration(ArrayDeclaration arraydec){ +        environment.defineVariable(arraydec.name.text, arraydec.type); +        String arrayString = ""; +        if(arraydec.type.equals("int")){ +            arrayString+="int "; +        } else if(arraydec.type.equals("real")){ +            arrayString+="real "; +        }  +        arrayString+=arraydec.name.text; +        for(Expression expr:arraydec.dimensions){ +            arrayString+="["; +            arrayString+=evaluateExpression(expr); +            arrayString+="]"; +        } +        arrayString+=";"; +        CCode.add(arrayString); + +         +    } +      private void evalBlockStatement(BlockStatement block){          for(Statement stmt:block.statements){              evaluateStatement(stmt); @@ -106,6 +129,9 @@ public class Translator{              else if (expr instanceof Expression.Variable){                  exprType=(String)environment.getVariable((((Expression.Variable)expr).name));              } +            else if (expr instanceof Expression.ArrayVariable){ +                exprType=(String)environment.getVariable((((Expression.ArrayVariable)expr).name)); +            }              if (exprType.equals("int")){                  types+="%d";              } else if (exprType.equals("double")){ @@ -162,6 +188,8 @@ public class Translator{              case "assign":                  evaluateAssignmentExpression((AssignmentExpression)expression);                  return ""; +            case "arrayvar": +                return evaluateArrayVariable((ArrayVariable)expression);              case "var":                  return evaluateVariableExpression((Variable)expression);              default: @@ -220,18 +248,39 @@ public class Translator{      }      private void evaluateAssignmentExpression(AssignmentExpression expr){ -        if(environment.checkVariable(expr.name)){ +        Token name=null; +        if(expr.variable instanceof Expression.Variable){ +            name = ((Expression.Variable)expr.variable).name; +        } +        else if(expr.variable instanceof Expression.ArrayVariable){ +            name = ((Expression.ArrayVariable)expr.variable).name; +        } +        if(environment.checkVariable(name)){              if(expr.value instanceof Expression.Literal){                  if(((Expression.Literal)expr.value).type.equals("string")){ -                    CCode.add("strcpy("+expr.name.text+","+evaluateExpression(expr.value)+");"); +                    CCode.add("strcpy("+evaluateExpression(expr.variable)+","+evaluateExpression(expr.value)+");");                  }else{ -                    CCode.add(expr.name.text+"="+evaluateExpression(expr.value)+";"); +                    CCode.add(evaluateExpression(expr.variable)+"="+evaluateExpression(expr.value)+";");                  }              }              else{ -                CCode.add(expr.name.text+"="+evaluateExpression(expr.value)+";"); +                CCode.add(evaluateExpression(expr.variable)+"="+evaluateExpression(expr.value)+";"); +            } +        } +    } + +    private String evaluateArrayVariable(ArrayVariable expr){ +        if(environment.checkVariable(expr.name)){ +            String arrayString=""; +            arrayString+=expr.name.text; +            for(Expression position:expr.positions){ +                arrayString+="["; +                arrayString+=evaluateExpression(position); +                arrayString+="]";              } +            return arrayString;          } +        return null;      }      private String evaluateVariableExpression(Variable expr){ | 
