diff options
| -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.exeBinary files differ index ee89ee8..1dded0a 100644 --- a/src/main.exe +++ b/src/main.exe | 
