/* Copyright (C) 2014-2016 A.Vontobel  
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * The license is in LICENCE-GPL.txt.
 * If not, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
 */

package net.sf.drawj2d.cmd;

import java.awt.Graphics2D;
import org.hecl.*;
//import org.hecl.java.*;
//import org.hecl.load.LoadCmd;
import org.hecl.files.FileCmds;
import org.hecl.files.HeclFileUtils;
//import org.hecl.files.HeclStreamCmds;
//import java.util.Vector;
import java.util.LinkedList;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import net.sf.drawj2d.cmd.geom.*;
import net.sf.drawj2d.cmd.statics.*;

/**
 *
 * @author av
 */
public class HCLparser {
    
    Graphics2D g;
    Interp interp;
    
    private boolean verbose = false;
    private final boolean debug = false;
    
    /**
     * Creates a new instance of HCLparser
     * @param g The graphic context. java.awt.Graphics2D
     */
    public HCLparser (Graphics2D g) {
        this.g = g;
        initialize();
    }
    
    public void setVerbose(boolean verbose) {
        this.verbose = verbose;
    }
    
    private void initialize() {
        API api = new API (g);
	//interp = null;
	try {
	    interp = new Interp();
	} catch (HeclException he) {
	    System.err.println("Error initializing the Hecl interpreter: " + he);
	    System.exit(1);
	}

        try {
	    /* Add the standard packages in. */
	    FileCmds.loadRestricted(interp); // command "source"
	    //FileCmds.load(interp);
	    //HeclStreamCmds.load(interp);
	    //Base64Cmd.load(interp);
	    //HttpCmd.load(interp);
	    //LoadCmd.load(interp);
	    //HeclJavaCmd.load(interp);
	    //NullCmd.load(interp);
            
            /*
	    Vector argv = new Vector();
            int i;
            for (i = 0; i < args.length; i++) {
                //System.out.println("(running " + args[i] + ")");
		argv.addElement(new Thing(args[i]));
            }
	    //interp.setVar("argv", ListThing.create(argv));
            */
            
	    extend(interp, api);
	    extendModules(interp, api);
	    extendHecl(interp, api);
            
        } catch (HeclException e) {
	    System.err.println("Hecl exception: " + e);
            e.printStackTrace();
        } 
        /*
        catch (Throwable t) { // necessary?
	    System.err.println("Java error: " + t);
	    t.printStackTrace();
	} */
    }

    /** Link hcl commands to the drawj2d.api classes. */
    private void extend(Interp ip, API api) throws HeclException {
	/*
	ip.addCommand("jones",new ObjectCmd());
	ip.addClassCmd(ObjectCmd.class,new ClCmd());
	*/
        ip.addCommand("unitlength", new UnitCmd(api));
        ip.addCommand("unitsize", new UnitCmd(api));
        ip.addCommand("line", new LineCmd(api));
        ip.addCommand("lineto", new LineCmd(api));
        ip.addCommand("l", new LineCmd(api));
        ip.addCommand("linetox", new LinetoxCmd(api, true));
        ip.addCommand("lx", new LinetoxCmd(api, true));
        ip.addCommand("linetoy", new LinetoxCmd(api, false));
        ip.addCommand("ly", new LinetoxCmd(api, false));
        ip.addCommand("linerel", new LinerelCmd(api));
        ip.addCommand("lr", new LinerelCmd(api));
        ip.addCommand("linepolar", new LinepolarCmd(api));
        ip.addCommand("lp", new LinepolarCmd(api));
        ip.addCommand("linemid", new LinemidCmd(api));
        ip.addCommand("lm", new LinemidCmd(api));
        ip.addCommand("arrow", new ArrowCmd(api));
        ip.addCommand("arrowto", new ArrowCmd(api));
        ip.addCommand("arrowrel", new ArrowrelCmd(api));
        ip.addCommand("arrows", new ArrowsCmd(api));
        ip.addCommand("arrowsto", new ArrowsCmd(api));
        ip.addCommand("arrowsrel", new ArrowsrelCmd(api));
        ip.addCommand("point", new PointCmd(api));
        ip.addCommand("pt", new PointCmd(api));
        ip.addCommand("p", new PointCmd(api)); // depreciate (0.6.3)
        ip.addCommand("dot", new DotCmd(api));
        ip.addCommand("moveto", new MovetoCmd(api));
        ip.addCommand("m", new MovetoCmd(api));
        ip.addCommand("movetox", new MovetoxCmd(api, true));
        ip.addCommand("mx", new MovetoxCmd(api, true));
        ip.addCommand("movetoy", new MovetoxCmd(api, false));
        ip.addCommand("my", new MovetoxCmd(api, false));
        ip.addCommand("moverel", new MoverelCmd(api));
        ip.addCommand("mr", new MoverelCmd(api));
        ip.addCommand("movepolar", new MovepolarCmd(api));
        ip.addCommand("mp", new MovepolarCmd(api));
        ip.addCommand("pen", new PenCmd(api));
        ip.addCommand("opacity", new OpacityCmd(api));
        ip.addCommand("circle", new CircleCmd(api));
        ip.addCommand("ellipse", new EllipseCmd(api));
        ip.addCommand("arc", new ArcCmd(api));
        ip.addCommand("segment", new SegmentCmd(api));
        ip.addCommand("sector", new SectorCmd(api));
        ip.addCommand("quadcurve", new QuadcurveCmd(api));
        ip.addCommand("parabola", new QuadcurveCmd(api));
        ip.addCommand("cubiccurve", new CubiccurveCmd(api));
        ip.addCommand("rect", new RectCmd(api));
        ip.addCommand("rectangle", new RectCmd(api));
        ip.addCommand("rod", new RodCmd(api));
        ip.addCommand("polygon", new PolygonCmd(api));
        ip.addCommand("box", new BoxCmd(api));
        ip.addCommand("label", new LabelCmd(api));
        ip.addCommand("lb", new LabelCmd(api));
        ip.addCommand("texlabel", new TexlabelCmd(api));
        ip.addCommand("tlb", new TexlabelCmd(api));
        ip.addCommand("text", new TextCmd(api));
        ip.addCommand("dimline", new DimlineCmd(api, false));
        ip.addCommand("texdimline", new DimlineCmd(api, true));
        ip.addCommand("dimlineto", new DimlineCmd(api, false));
        ip.addCommand("texdimlineto", new DimlineCmd(api, true));
        ip.addCommand("dimlinerel", new DimlinerelCmd(api, false));
        ip.addCommand("texdimlinerel", new DimlinerelCmd(api, true));
        ip.addCommand("dimangle", new DimangleCmd(api));
        ip.addCommand("texdimangle", new TexdimangleCmd(api));
        ip.addCommand("fillrectangle", new FillrectCmd(api));
        ip.addCommand("fillrect", new FillrectCmd(api));
        ip.addCommand("fillbox", new FillboxCmd(api));
        ip.addCommand("fillrod", new FillrodCmd(api));
        ip.addCommand("fillpolygon", new FillpolygonCmd(api));
        ip.addCommand("fillcircle", new FillcircleCmd(api));
        ip.addCommand("fillellipse", new FillellipseCmd(api));
        ip.addCommand("fillsegment", new FillsegmentCmd(api));
        ip.addCommand("fillsector", new FillsectorCmd(api));
        ip.addCommand("image", new ImageCmd(api));
        ip.addCommand("offset", new OffsetCmd(api));
        ip.addCommand("font", new FontCmd(api));
        ip.addCommand("forceunitlength", new ForceUnitCmd(api));
        ip.addCommand("force", new ForceCmd(api, false));
        ip.addCommand("texforce", new ForceCmd(api, true));
        ip.addCommand("force2", new Force2Cmd(api, false));
        ip.addCommand("texforce2", new Force2Cmd(api, true));
        ip.addCommand("expr", new ExprCmd(api));
        ip.addCommand("exprinput", new ExprinputCmd(api));
        ip.addCommand("here", new HereCmd(api));
        ip.addCommand("r", new HereCmd(api));
        ip.addCommand("mm", new MmCmd(api));
        ip.addCommand("fu", new FuCmd(api));
        ip.addCommand("kN", new FuCmd(api));
        ip.addCommand("nf", new NfCmd(api));
        ip.addCommand("assert", new AssertCmd());
        
        ip.addCommand("block", new BlockCmd(api));
        ip.addCommand("endblock", new EndblockCmd(api));
        ip.addCommand("block.rotate", new BlockrotateCmd(api));
        ip.addCommand("block.flip", new BlockflipCmd(api));
        ip.addCommand("block.scale", new BlockscaleCmd(api));
    }

    /** Link hcl commands to the drawj2d.api.[modules] classes. */
    private void extendModules(Interp ip, API api) throws HeclException {
        // Geometry
        ip.addCommand("geom.intersect", new GeomIntersectCmd());
        ip.addCommand("geom.intersectlinepath", new GeomIntersectlinepathCmd());
        ip.addCommand("geom.area", new GeomAreaCmd());
        ip.addCommand("geom.centroid", new GeomCentroidCmd());
        ip.addCommand("geom.vector", new GeomVectorCmd(api));
        ip.addCommand("geom.v", new GeomVectorCmd(api));
        ip.addCommand("geom.crossproduct", new GeomCrossproductCmd());
        ip.addCommand("geom.crossprod", new GeomCrossproductCmd());
        ip.addCommand("geom.dotproduct", new GeomDotproductCmd());
        ip.addCommand("geom.dotprod", new GeomDotproductCmd());
        ip.addCommand("geom.anglerad", new GeomAngleRadCmd(api));
        ip.addCommand("geom.angle", new GeomAngleCmd(api));
        ip.addCommand("geom.length", new GeomLengthCmd());
        ip.addCommand("geom.hypot", new GeomLengthCmd());
        ip.addCommand("geom.abs", new GeomLengthCmd());
        ip.addCommand("geom.norm", new GeomNormCmd());
        ip.addCommand("geom.online", new GeomOnlineCmd());
        ip.addCommand("geom.add", new GeomAddCmd());
        ip.addCommand("++", new GeomAddCmd());
        ip.addCommand("geom.subtract", new GeomSubtractCmd());
        ip.addCommand("--", new GeomSubtractCmd());
        ip.addCommand("geom.multiply", new GeomMultiplyCmd());
        ip.addCommand("**", new GeomMultiplyCmd());
        ip.addCommand("geom.divide", new GeomDivideCmd());
        ip.addCommand("//", new GeomDivideCmd());
        ip.addCommand("geom.rotate", new GeomRotateCmd());
        ip.addCommand("geom.polar", new GeomPolarCmd());
        ip.addCommand("geom.parallel", new GeomParallelCmd(api));
        ip.addCommand("geom.extend", new GeomExtendCmd());
        ip.addCommand("geom.distance", new GeomDistanceCmd(api));
        ip.addCommand("geom.dist", new GeomDistanceCmd(api));
        ip.addCommand("geom.azimuth", new GeomAzimuthCmd(api));
        ip.addCommand("geom.azi", new GeomAzimuthCmd(api));
        ip.addCommand("geom.tox", new GeomToxCmd(api, true));
        ip.addCommand("tx", new GeomToxCmd(api, true));
        ip.addCommand("geom.toy", new GeomToxCmd(api, false));
        ip.addCommand("ty", new GeomToxCmd(api, false));
        
        // Statics
        ip.addCommand("stat.add", new StatAddCmd());
        ip.addCommand("+++", new StatAddCmd());
        ip.addCommand("stat.subtract", new StatSubtractCmd());
        ip.addCommand("---", new StatSubtractCmd());
        ip.addCommand("stat.multiply", new StatMultiplyCmd());
        ip.addCommand("***", new StatMultiplyCmd());
        ip.addCommand("stat.abs", new StatAbsCmd());
        ip.addCommand("stat.move", new StatMoveCmd());
        ip.addCommand("stat.move2", new StatMove2Cmd(api));
        ip.addCommand("stat.actionline", new StatActionlineCmd(api));
        ip.addCommand("stat.distance", new StatDistanceCmd(api));
        ip.addCommand("stat.dist", new StatDistanceCmd(api));
        ip.addCommand("stat.moment", new StatMomentCmd(api));
        ip.addCommand("stat.mequi", new StatMequilibriumCmd(api));
        ip.addCommand("stat.equi", new StatEquilibriumCmd());
        ip.addCommand("stat.fequi", new StatFequilibriumCmd());
        ip.addCommand("stat.tip", new StatTipCmd(api));
    }

    /** Evaluate initial hecl commands. */
    private void extendHecl(Interp ip, API api) throws HeclException {
        ip.eval(new Thing("proc X {pos} {return [lindex $pos 0]}"));
        ip.eval(new Thing("proc Y {pos} {return [lindex $pos 1]}"));
        ip.eval(new Thing("proc XY {force} {return \"[lindex $force 0] [lindex $force 1]\"}"));
        ip.eval(new Thing("proc FX {force} {return [lindex $force 2]}"));
        ip.eval(new Thing("proc FY {force} {return [lindex $force 3]}"));
        ip.eval(new Thing("proc FXY {force} {return \"[lindex $force 2] [lindex $force 3]\"}"));
    }
    
    /** Let the interpreter source the input file
     * @param sourcefile source file or "_opt_stdin"
     * @return true if no exception has been caught. */
    public boolean sourceFile(String sourcefile) {
        boolean success = false;
        try {
	    if(!sourcefile.equals("_opt_stdin")) {
		HeclFileUtils.sourceFile(interp, sourcefile);
                success = true;
	    } else {
                // very slow! --> commented out in org.hecl.Interp.
		// interp.readEvalPrint(System.in,System.out,System.err);
                LinkedList sourcelist = new LinkedList();
                InputStreamReader eingabestrom;
                eingabestrom = new InputStreamReader(System.in, "UTF-8"); // Read Stdin
                BufferedReader eingabe = new BufferedReader(eingabestrom);
                String zeile;
                boolean isEOF = false;
                do {
                    zeile = eingabe.readLine();
                    if (zeile != null) sourcelist.add(zeile);
                    else isEOF = true;
                } while (isEOF == false);
                eingabe.close();
                eingabestrom.close();
                // Evaluate sourcelist
                if (verbose) System.out.println();
                int zeilennr = 0;
                for (String s : sourcelist) {
                    zeilennr++;
                    if (verbose) System.out.println(Fkt.nf(zeilennr, 3) + ":  " + s);
                    Thing input = new Thing(s);
                    Thing ans = interp.eval(input);
                    if (verbose) System.out.println("   @  " + ans.toString());
                }
                if (verbose) System.out.println();
                success = true;
	    }
        } catch (HeclException e) {
	    System.err.println("Hecl exception: " + e);
            if (debug) e.printStackTrace();
            success = false;
        } catch (IOException ex) {
	    System.err.println(ex.getLocalizedMessage());
            if (debug) ex.printStackTrace();
            success = false;
        }
        /*
        catch (Throwable t) { // necessary?
	    System.err.println("Java error: " + t);
	    t.printStackTrace();
            success = false;
	} */
	interp.terminate();
        return success;
    }
}

 

Ads help maintain this website.