summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com>2021-11-27 19:37:41 +0000
committerAidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com>2021-11-27 19:37:41 +0000
commit8badb0fab61a23dd81466c3f5f8aadd77bf952e3 (patch)
tree41a7e51e700ddee1a4e66aebfd3edaea29b60203 /src
parentac425713cfd5a4fac7ce5b607d722eeb9954ba10 (diff)
downloadesotericFORTRAN-8badb0fab61a23dd81466c3f5f8aadd77bf952e3.tar.gz
esotericFORTRAN-8badb0fab61a23dd81466c3f5f8aadd77bf952e3.zip
Added basic support for arrays
Diffstat (limited to 'src')
-rw-r--r--src/Compiler/Expression.java27
-rw-r--r--src/Compiler/Parser.java52
-rw-r--r--src/Compiler/Statement.java32
-rw-r--r--src/Compiler/TokenScanner.java1
-rw-r--r--src/Compiler/TokenType.java2
-rw-r--r--src/Compiler/Translator.java57
-rw-r--r--src/example.txt20
7 files changed, 150 insertions, 41 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){
diff --git a/src/example.txt b/src/example.txt
index 55236c1..22a2bfb 100644
--- a/src/example.txt
+++ b/src/example.txt
@@ -1,12 +1,8 @@
-int::n
-int::a
-int::b
-int::temp
-a=0
-b=2
-if (a==0.and.b==1) then
-print*,"true"
-else
-print*,"false"
-end if
-
+int dimension(5)::test
+int::i
+do i=0,4
+test(i)=i
+end do
+do i=0,4
+print*,test(i)
+end do \ No newline at end of file