Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import CPP.Absyn.*;
- import java.util.LinkedList;
- import java.util.HashMap;
- import java.util.Scanner;
- public class Interpreter {
- public static HashMap<String, DFun> signature = new HashMap<>();
- Scanner scn = new Scanner(System.in);
- public enum ValidType {
- INTEGER,
- DOUBLE,
- BOOL,
- VOID
- }
- private abstract class Value<R> implements Comparable<Value<R>>{
- public abstract R getValue();
- public abstract void setValue(R value);
- public abstract ValidType getType();
- public abstract int compareTo(Value<R> obj);
- }
- private class intValue extends Value<Integer> {
- private Integer value;
- private ValidType type = ValidType.INTEGER;
- public intValue(Integer value){
- this.value = value;
- }
- public Integer getValue(){
- return this.value;
- }
- public void setValue(Integer value){
- this.value = value;
- }
- public ValidType getType(){
- return this.type;
- }
- public int compareTo(Value<Integer> obj){
- return (this.value).compareTo(obj.getValue());
- }
- @Override
- public boolean equals(Object o) {
- if(o == null){
- return false;
- }
- if(o.getClass() != this.getClass()){
- return false;
- }
- intValue that = (intValue) o;
- return this.value.equals(that.getValue());
- }
- }
- private class doubleValue extends Value<Double> {
- private Double value;
- private ValidType type = ValidType.DOUBLE;
- public doubleValue(Double value){
- this.value = value;
- }
- public Double getValue(){
- return this.value;
- }
- public void setValue(Double value){
- this.value = value;
- }
- public ValidType getType(){
- return this.type;
- }
- public int compareTo(Value<Double> obj){
- return (this.value).compareTo(obj.getValue());
- }
- @Override
- public boolean equals(Object o) {
- if(o == null){
- return false;
- }
- if(o.getClass() != this.getClass()){
- return false;
- }
- doubleValue that = (doubleValue) o;
- return this.value.equals(that.getValue());
- }
- }
- private class boolValue extends Value<Boolean> {
- private Boolean value;
- private ValidType type = ValidType.BOOL;
- public boolValue(Boolean value){
- this.value = value;
- }
- public Boolean getValue(){
- return this.value;
- }
- public void setValue(Boolean value){
- this.value = value;
- }
- public ValidType getType(){
- return this.type;
- }
- public int compareTo(Value<Boolean> obj){
- return 0;
- }
- }
- private class Env {
- public LinkedList<HashMap<String, Value>> contexts = new LinkedList<HashMap<String, Value>>();
- public Env(HashMap<String, Value> funcArgs) {
- contexts.add(funcArgs);
- }
- public Env assignVar(String id, Value val) {
- for(int i = contexts.size()-1; i >= 0; i--){
- if(contexts.get(i).containsKey(id)){
- contexts.get(i).put(id, val);
- return this;
- }
- }
- throw new RuntimeException("Variable not declared");
- }
- public Env declareVar(String id) {
- if(contexts.getLast().containsKey(id)){
- throw new RuntimeException("Variable already declared");
- }
- contexts.getLast().put(id, null);
- return this;
- }
- public Env newBlock(){
- contexts.add(new HashMap<String, Value>());
- return this;
- }
- public Env exitBlock(){
- contexts.pollLast();
- return this;
- }
- public Value lookupVar(String id) {
- for(int i = contexts.size()-1; i >= 0; i--){
- if(contexts.get(i).containsKey(id)){
- return contexts.get(i).get(id);
- }
- }
- throw new RuntimeException("Variable not defined");
- }
- public DFun lookupFun(String id){
- if(signature.containsKey(id)){
- return signature.get(id);
- }
- else{
- throw new RuntimeException("Function not defined");
- }
- }
- }
- public void interpret(Program p) {
- Env env = new Env(new HashMap<String, Value>());
- PDefs defs = (PDefs) p;
- for(Def def : defs.listdef_){
- DFun function = ((DFun) def);
- signature.put(function.id_, function);
- }
- for(Def def: defs.listdef_){
- if((((DFun) def).id_).equals("main")){
- evalStms(env, ((DFun) def).liststm_);
- }
- }
- }
- public Value evalStms(Env env, ListStm stms){
- for(Stm stm : stms){
- Value retValue = evalStm(env, stm);
- if(retValue != null){
- return retValue;
- }
- }
- return null;
- }
- public Value evalStm(Env env, Stm stm) {
- return stm.accept(new StmEvaluator(), env);
- }
- private class StmEvaluator implements Stm.Visitor<Value, Env> {
- public Value visit(SExp p, Env env){
- evalExp(env, p.exp_);
- return null;
- }
- public Value visit(SDecls p, Env env){
- for(String id : p.listid_){
- env.declareVar(id);
- }
- return null;
- }
- public Value visit(SInit p, Env env){
- env.declareVar(p.id_);
- env.assignVar(p.id_, evalExp(env, p.exp_));
- return null;
- }
- public Value visit(SReturn p, Env env){
- return evalExp(env, p.exp_);
- }
- public Value visit(SWhile p, Env env){
- while(((intValue) evalExp(env, p.exp_)).getValue().equals(new Integer(1))){
- evalStm(env, p.stm_);
- }
- return null;
- }
- public Value visit(SBlock p, Env env){
- env.newBlock();
- Value v = evalStms(env, p.liststm_);
- env.exitBlock();
- return v;
- }
- public Value visit(SIfElse p, Env env){
- if(((intValue) evalExp(env, p.exp_)).getValue().equals(new Integer(1))){
- return evalStm(env, p.stm_1);
- }
- else{
- return evalStm(env, p.stm_2);
- }
- }
- }
- public Value evalExp(Env env, Exp exp) {
- return exp.accept(new ExpEvaluator(), env);
- }
- private class ExpEvaluator implements Exp.Visitor<Value, Env> {
- public Value visit(EPlus e, Env env) {
- Value val1 = evalExp(env, e.exp_1);
- Value val2 = evalExp(env, e.exp_2);
- if(val1.getType() == ValidType.INTEGER){
- return new intValue(((Integer)val1.getValue() + (Integer) val2.getValue()));
- }
- else{
- return new doubleValue(((Double)val1.getValue() + (Double) val2.getValue()));
- }
- }
- public Value visit(ETrue e, Env env) {
- return new intValue(1);
- }
- public Value visit(EFalse e, Env env) {
- return new intValue(0);
- }
- public Value visit(EInt e, Env env) {
- return new intValue(e.integer_);
- }
- public Value visit(EDouble e, Env env) {
- return new doubleValue(e.double_);
- }
- public Value visit(EId e, Env env) {
- return env.lookupVar(e.id_);
- }
- public Value visit(EApp e, Env env) {
- if(e.id_.equals("printInt")){
- System.out.println(evalExp(env, e.listexp_.get(0)).getValue());
- }
- else if(e.id_.equals("printDouble")){
- System.out.println(evalExp(env, e.listexp_.get(0)).getValue());
- }
- else if(e.id_.equals("readInt")){
- int x = scn.nextInt();
- return new intValue(x);
- }
- else if(e.id_.equals("readDouble")){
- double x = scn.nextDouble();
- return new doubleValue(x);
- }
- else{
- DFun function = env.lookupFun(e.id_);
- HashMap<String, Value> args = new HashMap<String, Value>();
- for(int i = 0; i < function.listarg_.size(); i++){
- args.put(((ADecl) function.listarg_.get(i)).id_, evalExp(env, e.listexp_.get(i)));
- }
- Env newEnv = new Env(args);
- return evalStms(newEnv, function.liststm_);
- }
- return null;
- }
- public Value visit(EPostIncr e, Env env) {
- Value val = evalExp(env, e.exp_);
- if(val.getType() == ValidType.INTEGER) {
- intValue x = (intValue) val;
- x.setValue(x.getValue()+1);
- intValue newValue = new intValue(((Integer) x.getValue())-1);
- return newValue;
- }
- else{
- doubleValue x = (doubleValue) val;
- x.setValue(x.getValue()+1);
- doubleValue newValue = new doubleValue(((Double) x.getValue())-1);
- return newValue;
- }
- }
- public Value visit(EPostDecr e, Env env) {
- Value val = evalExp(env, e.exp_);
- if(val.getType() == ValidType.INTEGER) {
- intValue x = (intValue) val;
- x.setValue(x.getValue()-1);
- intValue newValue = new intValue(((Integer) x.getValue())+1);
- return newValue;
- }
- else{
- doubleValue x = (doubleValue) val;
- x.setValue(x.getValue()-1);
- doubleValue newValue = new doubleValue(((Double) x.getValue())+1);
- return newValue;
- }
- }
- public Value visit(EPreIncr e, Env env) {
- Value val = evalExp(env, e.exp_);
- if(val.getType() == ValidType.INTEGER){
- intValue x = (intValue) val;
- x.setValue(x.getValue()+1);
- return x;
- }
- else{
- doubleValue x = (doubleValue) val;
- x.setValue(x.getValue()+1);
- return x;
- }
- }
- public Value visit(EPreDecr e, Env env) {
- Value val = evalExp(env, e.exp_);
- if(val.getType() == ValidType.INTEGER){
- intValue x = (intValue) val;
- x.setValue(x.getValue()-1);
- return x;
- }
- else{
- doubleValue x = (doubleValue) val;
- x.setValue(x.getValue()-1);
- return x;
- }
- }
- public Value visit(ETimes e, Env env) {
- Value val1 = evalExp(env, e.exp_1);
- Value val2 = evalExp(env, e.exp_2);
- if(val1.getType() == ValidType.INTEGER){
- return new intValue(((Integer)val1.getValue() * (Integer) val2.getValue()));
- }
- else{
- return new doubleValue(((Double)val1.getValue() * (Double) val2.getValue()));
- }
- }
- public Value visit(EDiv e, Env env) {
- Value val1 = evalExp(env, e.exp_1);
- Value val2 = evalExp(env, e.exp_2);
- if(val1.getType() == ValidType.INTEGER){
- return new intValue(((Integer)val1.getValue() / (Integer) val2.getValue()));
- }
- else{
- return new doubleValue(((Double)val1.getValue() / (Double) val2.getValue()));
- }
- }
- public Value visit(EMinus e, Env env) {
- Value val1 = evalExp(env, e.exp_1);
- Value val2 = evalExp(env, e.exp_2);
- if(val1.getType() == ValidType.INTEGER){
- return new intValue(((Integer)val1.getValue() - (Integer) val2.getValue()));
- }
- else{
- return new doubleValue(((Double)val1.getValue() - (Double) val2.getValue()));
- }
- }
- public Value visit(ELt e, Env env) {
- Value val1 = evalExp(env, e.exp_1);
- Value val2 = evalExp(env, e.exp_2);
- if(val1.getType() == ValidType.INTEGER){
- int result = ((intValue) val1).compareTo(((intValue) val2));
- if(result == -1){
- return new intValue(1);
- }
- else{
- return new intValue(0);
- }
- }
- else{
- int result = ((doubleValue) val1).compareTo(((doubleValue) val2));
- if(result == -1){
- return new intValue(1);
- }
- else{
- return new intValue(0);
- }
- }
- }
- public Value visit(EGt e, Env env) {
- Value val1 = evalExp(env, e.exp_1);
- Value val2 = evalExp(env, e.exp_2);
- if(val1.getType() == ValidType.INTEGER){
- int result = ((intValue) val1).compareTo(((intValue) val2));
- if(result == 1){
- return new intValue(1);
- }
- else{
- return new intValue(0);
- }
- }
- else{
- int result = ((doubleValue) val1).compareTo(((doubleValue) val2));
- if(result == 1){
- return new intValue(1);
- }
- else{
- return new intValue(0);
- }
- }
- }
- public Value visit(ELtEq e, Env env) {
- Value val1 = evalExp(env, e.exp_1);
- Value val2 = evalExp(env, e.exp_2);
- if(val1.getType() == ValidType.INTEGER){
- int result = ((intValue) val1).compareTo(((intValue) val2));
- if(result <= 0){
- return new intValue(1);
- }
- else{
- return new intValue(0);
- }
- }
- else{
- int result = ((doubleValue) val1).compareTo(((doubleValue) val2));
- if(result <= 0){
- return new intValue(1);
- }
- else{
- return new intValue(0);
- }
- }
- }
- public Value visit(EGtEq e, Env env) {
- Value val1 = evalExp(env, e.exp_1);
- Value val2 = evalExp(env, e.exp_2);
- if(val1.getType() == ValidType.INTEGER){
- int result = ((intValue) val1).compareTo(((intValue) val2));
- if(result >= 0){
- return new intValue(1);
- }
- else{
- return new intValue(0);
- }
- }
- else{
- int result = ((doubleValue) val1).compareTo(((doubleValue) val2));
- if(result >= 0){
- return new intValue(1);
- }
- else{
- return new intValue(0);
- }
- }
- }
- public Value visit(EEq e, Env env) {
- if (evalExp(env, e.exp_1).equals(evalExp(env, e.exp_2)))
- return new intValue(1);
- return new intValue(0);
- }
- public Value visit(ENEq e, Env env) {
- if (!(evalExp(env, e.exp_1).equals(evalExp(env, e.exp_2))))
- return new intValue(1);
- return new intValue(0);
- }
- public Value visit(EAnd e, Env env) {
- intValue val1 = (intValue) evalExp(env, e.exp_1);
- if(val1.getValue() == 0){
- return new intValue(0);
- }
- intValue val2 = (intValue) evalExp(env, e.exp_2);
- if(val2.getValue() == 0){
- return new intValue(0);
- }
- return new intValue(1);
- }
- public Value visit(EOr e, Env env) {
- intValue val1 = (intValue) evalExp(env, e.exp_1);
- if(val1.getValue() == 1){
- return new intValue(1);
- }
- intValue val2 = (intValue) evalExp(env, e.exp_2);
- if(val2.getValue() == 1){
- return new intValue(1);
- }
- return new intValue(0);
- }
- public Value visit(EAss e, Env env) {
- env.assignVar(((EId) e.exp_1).id_, evalExp(env, e.exp_2));
- //System.out.println("VALUE: " + ((intValue)env.lookupVar(((EId) e.exp_1).id_)).getValue().toString());
- return env.lookupVar(((EId) e.exp_1).id_);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement