Yeti API documentation

anttask

yeti.lang.compiler.repl

sourcecode

Overview

 * Yeti compiler and REPL interface.
 * Copyright (c) 2008.2009 Madis Janson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

Module Type

array<string> -> {
   var classPath is list<string>,
   compilationOf is ~yeti.lang.compiler.CodeWriter -> ~yeti.lang.compiler.CompileCtx,
   var evalContext is ~yeti.lang.compiler.YetiEval,
   evaluate is string -> number -> string,
   execClass is boolean -> ~java.lang.ClassLoader -> ~java.lang.Object,
   var gcj is boolean,
   getTrace is ~java.lang.Throwable -> string,
   var mainClass is string,
   var noframes is boolean,
   var preload is list<string>,
   reader is ~yeti.lang.compiler.YetiC,
   var sandbox is boolean
}

Source

/**
 * Yeti compiler and REPL interface.
 * Copyright (c) 2008.2009 Madis Janson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
module yeti.lang.compiler.repl;

import java.lang: Class, ClassLoader;
import yeti.lang.Core;
import java.security.Permission;
import java.io.File;

do argv: {
    var preload = ["yeti/lang/std", "yeti/lang/io"],
    var mainClass = "code",
    var classPath = [],
    var sandbox = false,
    var gcj = false,
    var noframes = false,
    var evalContext = () as ~YetiEval,
    reader = new YetiC(),

    compilationOf writer =
        ctx = new CompileCtx(reader, writer, preload,
                             new ClassFinder(classPath as ~String[]));
        if gcj then
            ctx#isGCJ := true
        fi;
        if noframes then
            ctx#classWriterFlags := 0
        fi;
        ctx,

    getTrace ex is ~java.lang.Throwable -> string =
        sw = new java.io.StringWriter();
        ex#printStackTrace(new java.io.PrintWriter(sw));
        sw#toString(),

    execClass eval writer =
        c = Class#forName(strReplace '/' '.' mainClass, true, writer);
        try
            if eval then
                f = c#newInstance() unsafely_as () -> 'a;
                if sandbox then
                    var sandboxed = \();
                    class Sandbox extends java.lang.SecurityManager
                        void checkPermission(Permission perm)
                            sandboxed (),
                        void checkPermission(Permission perm, Object context)
                            sandboxed (),
                        void checkExit(int status)
                            ()
                    end;
                    System#setSecurityManager(new Sandbox());
                    // can't activate before, because
                    // setSecurityManager would fail otherwise
                    sandboxed := \throw new java.lang.SecurityException();
                fi;
                f ()
            else
                aa = new Object[1];
                aa.[0] := argv is array<string> as ~String[] as ~Object;
                c#getMethod("main", [classOf String[]])#invoke((), aa)
            fi
        catch java.lang.reflect.InvocationTargetException ex:
            t = ex#getCause();
            throw if defined? t then t else ex fi;
        yrt,

    evaluate line flags =
        writer = new Loader();
        res = array [];
        oldContext = YetiEval#get();
        if defined? evalContext or not defined? oldContext then
            if not defined? evalContext then
                evalContext := new YetiEval()
            fi;
            YetiEval#set(evalContext)
        fi;
        try
            bindings = YetiEval#get()#bindings;
            bindBarrier = bindings#size();
            compilation = compilationOf writer;
            type_ = compilation#compile((), mainClass, line is string, flags +
                                            YetiC#CF_EVAL + YetiC#CF_EVAL_BIND);
            try
                val = execClass true writer;
                if type_#deref()#type != YetiType#UNIT then
                    push res "\(Core#show(val)) is \(type_)"
                fi
            catch Exception ex:
                push res (getTrace ex)
            catch java.lang.StackOverflowError ex:
                push res (getTrace ex)
            yrt;
            for [bindBarrier .. bindings#size() - 1] do i:
                binding = bindings#get(i) unsafely_as ~YetiEval$Binding;
                if not binding#isImport then
                    t = binding#type;
                    push res "\(if binding#mutable then "var " else "" fi)\
                             "\(binding#name) is \(t) = \
                             "\(if t#deref()#type == YetiType#UNIT then
                                    "()"
                                elif nullptr? binding#value then
                                    "<undef>"
                                else
                                    Core#show(binding#val())
                                fi)"
                fi
            done
        catch CompileException ex:
            push res ex#getMessage()
        finally
            YetiEval#set(oldContext)
        yrt;
        strJoin '' (map (^ "\n") res),

    /* deprecated
    compileToFiles sources target printMessage
            is list?<string> -> string -> (~CompileException -> ()) -> boolean =
        target = if target == "" then "" else target ^ File#separator fi;
        compilation = compilationOf new ToFile(target);
        try
            for sources do src:
                mainClass := compilation#compile(src, 0)
            done;
            compilation#enumWarns(printMessage);
            true
        catch CompileException ex:
            compilation#enumWarns(printMessage);
            printMessage ex;
            false
        yrt*/
} done