diff options
author | AidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com> | 2021-11-07 01:23:19 +0000 |
---|---|---|
committer | AidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com> | 2021-11-07 01:23:19 +0000 |
commit | f8b888716211b78900db62ede497fa4ac2100c00 (patch) | |
tree | 3ea66c732de6abb95b10e708d0ab33651cb6b327 /src | |
parent | d3046e3b1481cf6d190b8fcb814985e29852b5eb (diff) | |
download | esotericFORTRAN-f8b888716211b78900db62ede497fa4ac2100c00.tar.gz esotericFORTRAN-f8b888716211b78900db62ede497fa4ac2100c00.zip |
Basic floating point support and small improvements to error handing
Diffstat (limited to 'src')
-rw-r--r-- | src/Compiler/Environment.java | 3 | ||||
-rw-r--r-- | src/Compiler/Expression.java | 4 | ||||
-rw-r--r-- | src/Compiler/Language.java | 11 | ||||
-rw-r--r-- | src/Compiler/Parser.java | 47 | ||||
-rw-r--r-- | src/Compiler/Statement.java | 4 | ||||
-rw-r--r-- | src/Compiler/TokenScanner.java | 11 | ||||
-rw-r--r-- | src/Compiler/TokenType.java | 3 | ||||
-rw-r--r-- | src/Compiler/Translator.java | 27 | ||||
-rw-r--r-- | src/example.txt | 10 | ||||
-rw-r--r-- | src/main.c | 13 | ||||
-rw-r--r-- | src/main.exe | bin | 297800 -> 297800 bytes |
11 files changed, 91 insertions, 42 deletions
diff --git a/src/Compiler/Environment.java b/src/Compiler/Environment.java index 0e682a4..3ccf425 100644 --- a/src/Compiler/Environment.java +++ b/src/Compiler/Environment.java @@ -5,11 +5,13 @@ import java.util.Map; public class Environment { private final Map<String,Object> variableMap = new HashMap<>(); + //Define a variable inside the current environment //Maybe check if variable is already defined? public void defineVariable(String name,Object value){ variableMap.put(name, value); } + //Get a variable if it is defined, or report an error public Object getVariable(String name){ if(variableMap.containsKey(name)){ return variableMap.get(name); @@ -18,6 +20,7 @@ public class Environment { throw new Error(); } + //Assign a value to an existing variable public void assignVariable(String name,Object value){ if(variableMap.containsKey(name)){ variableMap.put(name, value); diff --git a/src/Compiler/Expression.java b/src/Compiler/Expression.java index 63ed7f2..7605c8b 100644 --- a/src/Compiler/Expression.java +++ b/src/Compiler/Expression.java @@ -22,9 +22,11 @@ abstract class Expression { static class Literal extends Expression{ final Token value; + final String type; - Literal(Token value){ + Literal(Token value,String type){ this.value=value; + this.type=type; } diff --git a/src/Compiler/Language.java b/src/Compiler/Language.java index 9151bd5..44168db 100644 --- a/src/Compiler/Language.java +++ b/src/Compiler/Language.java @@ -39,25 +39,34 @@ public class Language { } } - //Extract and print each token + //Function to take source code and output the result private static void runInterpreter(String sourceCode){ + + //Extract tokens from the source code TokenScanner scanner = new TokenScanner(); List<Token> tokens = scanner.extractTokens(sourceCode); //for (Token token : tokens) { // System.out.println(token); //} if (hadError) return; + //Parse into AST Parser parser = new Parser(tokens); List<Statement> ast = parser.parse(); if (hadError) return; + + //Translate AST into equivalent C code Translator translator = new Translator(); List<String> code = translator.compileToC(ast); if (hadError) return; + + //Execute created C code ExecuteC cExecutor = new ExecuteC(); cExecutor.compileAndExecuteC(code); } + + //Basic error reporting static void displayError(String message){ hadError=true; System.out.println("An error was encountered"); diff --git a/src/Compiler/Parser.java b/src/Compiler/Parser.java index 412289a..68851bf 100644 --- a/src/Compiler/Parser.java +++ b/src/Compiler/Parser.java @@ -13,28 +13,37 @@ public class Parser { List<Statement> parse(){ List<Statement> statements = new ArrayList<>(); - while (!checkEOF()){ - statements.add(declaration()); + try{ + while (!checkEOF()){ + statements.add(declaration()); + } + }catch (Error e){ + return null; } return statements; } + + //Clean up and reduce code mess private Statement declaration(){ - try{ - if (matchAndAdvance(TokenType.VAR)){ - if (matchOrError(TokenType.DEFINE, ":: Required for variable definition")){ - if (matchOrError(TokenType.IDENTIFIER,"Expected variable name.")){ - Token varName = getPreviousToken(); - return new Statement.VariableDeclaration(varName); - } - } + if (matchAndAdvance(TokenType.INT)){ + if (matchOrError(TokenType.DEFINE, ":: Required for variable definition")){ + if (matchOrError(TokenType.IDENTIFIER,"Expected variable name.")){ + Token varName = getPreviousToken(); + return new Statement.VariableDeclaration(varName,"int"); + } + } + } else if (matchAndAdvance(TokenType.REAL)){ + if (matchOrError(TokenType.DEFINE, ":: Required for variable definition")){ + if (matchOrError(TokenType.IDENTIFIER,"Expected variable name.")){ + Token varName = getPreviousToken(); + return new Statement.VariableDeclaration(varName,"real"); + } } - return statement(); - } catch (Error e){ - currentToken++; - return null; } + + return statement(); } private Statement statement(){ @@ -55,14 +64,14 @@ public class Parser { List<Statement> statements = new ArrayList<>(); List<Statement> elseStatements = new ArrayList<>(); while(!matchAndAdvance(TokenType.ENDIF)&&!checkToken(TokenType.ELSE)){ - if(matchAndAdvance(TokenType.EOF)){ + if(checkEOF()){ throw error("endif missing"); } statements.add(declaration()); } if(matchAndAdvance(TokenType.ELSE)){ while(!matchAndAdvance(TokenType.ENDIF)){ - if(matchAndAdvance(TokenType.EOF)){ + if(checkEOF()){ throw error("endif missing"); } elseStatements.add(declaration()); @@ -140,7 +149,11 @@ public class Parser { private Expression primary(){ if (matchAndAdvance(TokenType.NUMBER)){ - return new Expression.Literal(getPreviousToken()); + if(getPreviousToken().value instanceof Integer){ + return new Expression.Literal(getPreviousToken(),"int"); + } else if(getPreviousToken().value instanceof Double){ + return new Expression.Literal(getPreviousToken(),"double"); + } } if (matchAndAdvance(TokenType.IDENTIFIER)) { diff --git a/src/Compiler/Statement.java b/src/Compiler/Statement.java index 6b58878..a74009d 100644 --- a/src/Compiler/Statement.java +++ b/src/Compiler/Statement.java @@ -37,12 +37,14 @@ abstract class Statement { static class VariableDeclaration extends Statement{ - VariableDeclaration(Token name){ + VariableDeclaration(Token name,String type){ this.name=name; + this.type=type; } final Token name; + final String type; @Override public String getStatmentType() { diff --git a/src/Compiler/TokenScanner.java b/src/Compiler/TokenScanner.java index 7783c01..27501fa 100644 --- a/src/Compiler/TokenScanner.java +++ b/src/Compiler/TokenScanner.java @@ -79,17 +79,23 @@ public class TokenScanner { //Check for numer if (checkIsDigit(checkChar)){ + String type = "int"; while (checkIsDigit(lookAhead())){ currentLoc++; } //Check if number contains a decimal point if (lookAhead()=='.' && checkIsDigit(lookTwoAhead())){ + type="double"; currentLoc++; while (checkIsDigit(lookAhead())){ currentLoc++; } } - createToken(TokenType.NUMBER, Double.parseDouble(sourceCode.substring(tokenStart, currentLoc+1))); + if (type.equals("double")){ + createToken(TokenType.NUMBER, Double.parseDouble(sourceCode.substring(tokenStart, currentLoc+1))); + } else{ + createToken(TokenType.NUMBER, Integer.parseInt(sourceCode.substring(tokenStart, currentLoc+1))); + } } else if (checkIsAlpha(checkChar)){ while (checkIsAlpha(lookAhead())){ @@ -173,7 +179,8 @@ public class TokenScanner { static { keywords = new HashMap<>(); - keywords.put("var", TokenType.VAR); + keywords.put("int", TokenType.INT); + keywords.put("real", TokenType.REAL); keywords.put("print", TokenType.PRINT); keywords.put("if", TokenType.IF); keywords.put("then", TokenType.THEN); diff --git a/src/Compiler/TokenType.java b/src/Compiler/TokenType.java index f916f1e..f56bf38 100644 --- a/src/Compiler/TokenType.java +++ b/src/Compiler/TokenType.java @@ -1,5 +1,6 @@ package Compiler; +//List of valid token types public enum TokenType { EQUALS, LEFT_PAREN, RIGHT_PAREN, PLUS, MINUS, SLASH, STAR, SEMI_COLON, @@ -11,7 +12,7 @@ public enum TokenType { NUMBER,IDENTIFIER, - VAR,PRINT,IF,THEN,ENDIF,ELSE, + INT,REAL,PRINT,IF,THEN,ENDIF,ELSE, EOF } diff --git a/src/Compiler/Translator.java b/src/Compiler/Translator.java index 5848389..716bafd 100644 --- a/src/Compiler/Translator.java +++ b/src/Compiler/Translator.java @@ -53,12 +53,30 @@ public class Translator{ } private void evalVariableDeclaration(VariableDeclaration vardec){ - environment.defineVariable(vardec.name.text, null); - CCode.add("int "+vardec.name.text+";"); + environment.defineVariable(vardec.name.text, vardec.type); + if(vardec.type.equals("int")){ + CCode.add("int "+vardec.name.text+";"); + } else if(vardec.type.equals("real")){ + CCode.add("float "+vardec.name.text+";"); + } } private void evalPrintStatement(PrintStatement print){ - CCode.add("printf(\"%d\","+evaluateExpression(print.expr)+");"); + if(print.expr instanceof Expression.Literal){ + if (((Expression.Literal)print.expr).type.equals("int")){ + CCode.add("printf(\"%d\","+evaluateExpression(print.expr)+");"); + } else if (((Expression.Literal)print.expr).type.equals("double")){ + CCode.add("printf(\"%f\","+evaluateExpression(print.expr)+");"); + } + } else if (print.expr instanceof Expression.Variable){ + Object varValue = environment.getVariable((((Expression.Variable)print.expr).name).text); + if (varValue.equals("int")){ + CCode.add("printf(\"%d\","+evaluateExpression(print.expr)+");"); + } else if (varValue.equals("real")){ + CCode.add("printf(\"%f\","+evaluateExpression(print.expr)+");"); + } + } + } private void evalIfStatement(IfStatement ifstatement){ @@ -127,8 +145,6 @@ public class Translator{ } private void evaluateAssignmentExpression(AssignmentExpression expr){ - Object assignedValue = evaluateExpression(expr.value); - environment.assignVariable(expr.name.text, assignedValue); CCode.add(expr.name.text+"="+evaluateExpression(expr.value)+";"); } @@ -137,6 +153,7 @@ public class Translator{ } + } diff --git a/src/example.txt b/src/example.txt index 94a8091..886e85c 100644 --- a/src/example.txt +++ b/src/example.txt @@ -1,8 +1,6 @@ -var :: a -a=5 -if a<2 then -a=a+5 -else -a=a-3 +real :: a +a=6 +if a>2 then +a=a+0.5 endif print a @@ -1,12 +1,9 @@ #include <stdio.h> int main(){ -int a; -a=5.0; -if(a<2.0){ -a=a+5.0; +float a; +a=6; +if(a>2){ +a=a+0.5; } -else { -a=a-3.0; -} -printf("%d",a); +printf("%f",a); } diff --git a/src/main.exe b/src/main.exe Binary files differindex ee89ee8..1dded0a 100644 --- a/src/main.exe +++ b/src/main.exe |