summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com>2021-11-07 01:23:19 +0000
committerAidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com>2021-11-07 01:23:19 +0000
commitf8b888716211b78900db62ede497fa4ac2100c00 (patch)
tree3ea66c732de6abb95b10e708d0ab33651cb6b327 /src
parentd3046e3b1481cf6d190b8fcb814985e29852b5eb (diff)
downloadesotericFORTRAN-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.java3
-rw-r--r--src/Compiler/Expression.java4
-rw-r--r--src/Compiler/Language.java11
-rw-r--r--src/Compiler/Parser.java47
-rw-r--r--src/Compiler/Statement.java4
-rw-r--r--src/Compiler/TokenScanner.java11
-rw-r--r--src/Compiler/TokenType.java3
-rw-r--r--src/Compiler/Translator.java27
-rw-r--r--src/example.txt10
-rw-r--r--src/main.c13
-rw-r--r--src/main.exebin297800 -> 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
diff --git a/src/main.c b/src/main.c
index 729227f..055bc9d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
index ee89ee8..1dded0a 100644
--- a/src/main.exe
+++ b/src/main.exe
Binary files differ