package xhl.core;

import xhl.core.exceptions.*;

public class Evaluator {
    private final SymbolTable symbolTable = new SymbolTable();

    public void loadModule(Module module) {
        symbolTable.putAll(module.getSymbols());
    }

    public Object eval(Object obj) throws EvaluationException {
        if (obj instanceof Symbol) {
            Symbol sym = (Symbol) obj;
            if (symbolTable.containsKey(sym))
                return symbolTable.get(sym);
            else
                throw new SymbolNotDefinedException(sym);
        } else if (obj instanceof CodeList) {
            CodeList list = (CodeList) obj;
            Object head = list.head();
            if (!(head instanceof Symbol))
                throw new HeadIsNotSymbolException();
            Object func = eval(head);
            if (!(func instanceof Executable))
                throw new FunctionUndefinedException((Symbol) head);
            return ((Executable) func).exec(list.tail());
        } else {
            return obj;
        }
    }

    public Object evalAll(CodeList exprs) throws EvaluationException {
        Object result = null;
        for (Object expr : exprs) {
            result = eval(expr);
        }
        return result;
    }

    public void putSymbol(Symbol sym, Object value) {
        symbolTable.put(sym, value);
    }

    public Object getSymbol(Symbol sym) {
        return symbolTable.get(sym);
    }
}

@@ -43,16 +43,77 @@
 ons.*;%0A%0A
+/**%0A * XHL code evaluator.%0A *%0A * @author Sergej Chodarev%0A */%0A
 public c
@@ -285,32 +285,214 @@
 bols());%0A    %7D%0A%0A
+    /**%0A     * Evaluate language object.%0A     *%0A     * @param obj%0A     *            object to evaluate%0A     * @return result of evaluation%0A     * @throws EvaluationException%0A     */%0A
     public Objec
@@ -843,44 +843,171 @@
     
-CodeList list = (CodeList) obj;%0A    
+return evalList((CodeList) obj);%0A        %7D else %7B%0A            return obj;%0A        %7D%0A    %7D%0A%0A    private Object evalList(CodeList list) throws EvaluationException %7B%0A
     
@@ -1041,28 +1041,24 @@
 ();%0A        
-    
 if (!(head i
@@ -1080,36 +1080,32 @@
 l))%0A            
-  
-  
 throw new HeadIs
@@ -1130,28 +1130,24 @@
 ();%0A        
-    
 Object func 
@@ -1156,28 +1156,24 @@
 eval(head);%0A
-    
         if (
@@ -1207,36 +1207,32 @@
 e))%0A            
-    
 throw new Functi
@@ -1272,28 +1272,24 @@
 d);%0A        
-    
 return ((Exe
@@ -1330,61 +1330,222 @@
     
+%7D%0A%0A
     
-%7D else %7B%0A            return obj;%0A        %7D
+/**%0A     * Evaluate list of program expressions%0A     *%0A     * @param exprs%0A     *            list containing program expressions%0A     * @return result of evaluation%0A     * @throws EvaluationException
 %0A    
-%7D%0A
+ */
 %0A   
@@ -1743,32 +1743,133 @@
  result;%0A    %7D%0A%0A
+    /**%0A     * Put symbol into symbol table.%0A     *%0A     * @param symbol%0A     * @param value%0A     */%0A
     public void 
@@ -1888,16 +1888,19 @@
 mbol sym
+bol
 , Object
@@ -1936,16 +1936,19 @@
 .put(sym
+bol
 , value)
@@ -1952,24 +1952,158 @@
 ue);%0A    %7D%0A%0A
+    /**%0A     * Get value of symbol from symbol table.%0A     *%0A     * @param symbol%0A     * @return value associated with symbol%0A     */%0A
     public O
@@ -2128,16 +2128,19 @@
 mbol sym
+bol
 ) %7B%0A    
@@ -2165,23 +2165,26 @@
 able.get(sym
+bol
 );%0A    %7D%0A%7D%0A

Refactor Evaluator