All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zoomba.lang.Main Maven / Gradle / Ivy

Go to download

ZoomBA is a multi paradigm Micro Language for JVM Scripting used for business development and software testing

The newest version!
/*
 * Copyright 2017 zoomba-lang.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package zoomba.lang;

import org.jline.reader.*;
import org.jline.reader.impl.DefaultParser;
import org.jline.reader.impl.history.DefaultHistory;
import org.jline.reader.impl.completer.StringsCompleter;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import zoomba.lang.core.interpreter.ZContext;
import zoomba.lang.core.interpreter.ZContext.*;
import zoomba.lang.core.interpreter.ZInterpret;
import zoomba.lang.core.interpreter.ZScript;
import zoomba.lang.core.operations.Function;
import zoomba.lang.core.types.ZException;
import zoomba.lang.core.types.ZTypes;

import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;

import static zoomba.lang.core.interpreter.ZContext.ArgContext.EMPTY_ARGS_CONTEXT;
import static zoomba.lang.core.interpreter.ZContext.EMPTY_CONTEXT;

/**
 * One stop shop for Entry Point
 */
public class Main {

    private static final String PROMPT = "(zoomba)";

    private static final String QUIT = "//q";

    private static final String VARS = "//v";

    private static final String HELP = "//h";

    public static final String RUN = "//r";

    public static final String CLEAR_BP = "//c";

    private static final String BUILD_VERSION_AND_TIME = getBuildVersionAndTime();

    public static String debugContext(FunctionContext context){
        StringBuilder buf = new StringBuilder();
        buf.append("context : { \n");
        for ( String s : context.map.keySet() ){
            Object o = context.map.get(s);
            String v = String.valueOf( o );
            buf.append(s).append(" => ").append(v);
            if ( o != null ){
                buf.append(" /* ").append( o.getClass() ).append(" */");
            }
            buf.append("\n");
        }
        buf.append("}\n");
        return buf.toString();
    }

    private static void showHelp(PrintConsole console){
        console.printf("//h brings this help.%n");
        console.printf("//h key_word : shows help about the keyword %n");
        console.printf("//q quits REPL. In debug mode runs till next BreakPoint %n");
        console.printf("//v shows variables. %n");
        console.printf("//c In debug mode, clear this Breakpoint. %n");
        console.printf("//r loads and runs a script from REPL.%n");
        console.printf("Enjoy ZoomBA...(%s)%n", BUILD_VERSION_AND_TIME);
    }

    private static void showCommandHelp(PrintConsole console, Map commandMap, String command){
        if ( !commandMap.containsKey( command ) ){
            console.printf("No Help Available on [%s]\n", command);
            return;
        }
        Map help = commandMap.get( command );
        console.printf("========= Description ========\n%s\n", help.get("desc") );
        console.printf("========= Syntax ========\n%s\n", help.get("syn") );
        console.printf("======== Samples ========\n%s\n", ZTypes.string( (Iterable)help.get("samples") , "\n") );
        console.printf("Read Further at : %s\n", help.get("url") );
    }

    public static synchronized boolean bpToBeCleared(ZContext context){
        Function.MonadicContainer c = context.get( CLEAR_BP );
        if ( c.isNil() ) return false;
        return ZTypes.bool(c.value(),false);
    }

    public static synchronized void clearFromContext(ZContext context){
        if ( !context.has( CLEAR_BP ) ) return;
        context.unSet( CLEAR_BP );
    }

    private static class PrintConsole {

        private final Console console ;

        private PrintConsole(){
            console = System.console();
        }

        public void printf(String fmt, Object...args){
            if (console == null ){
                System.out.printf(fmt,args);
            } else {
                console.printf(fmt,args);
            }
        }
    }

    public static void stepDance(FunctionContext replContext) throws Exception {
        Terminal terminal = TerminalBuilder.builder().system(true).build();
        Parser parser = new DefaultParser();

        PrintConsole console = new PrintConsole();
        Path historyFile = Paths.get(System.getProperty("user.home"), ".zm_cli_history");
        if (!historyFile.toFile().exists()) {
            Files.createFile(historyFile);
        }


        LineReader consoleReader = LineReaderBuilder.builder().terminal(terminal).completer( new StringsCompleter(
                new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream("/keyWords.txt"),
                        StandardCharsets.UTF_8)).lines().collect(Collectors.toList())
        )).parser(parser).build();
        consoleReader.setVariable(LineReader.HISTORY_FILE,historyFile);
        consoleReader.setOpt(LineReader.Option.DISABLE_EVENT_EXPANSION);
        History history = new DefaultHistory(consoleReader);

        String result = new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream("/help.json"))).
                lines().parallel().collect(Collectors.joining("\n"));

        Map helpMap = (Map)ZTypes.json( result );

        ZScript zs ;
        Function.MonadicContainer c;
        if ( replContext == null ) {
            replContext = new FunctionContext(EMPTY_CONTEXT, EMPTY_ARGS_CONTEXT);
        }
        showHelp(console);
        while (true) {
            String txt = consoleReader.readLine(PROMPT);
            txt = txt.trim();
            if ( txt.startsWith(QUIT) ) break;
            if ( txt.startsWith( CLEAR_BP ) ){
                replContext.set(CLEAR_BP,true);
                break;
            }
            if ( VARS.equals(txt) ){
                // show variables
                console.printf("%s\n", debugContext(replContext) );
                continue;
            }
            if ( txt.startsWith(HELP) ){
                String[] words = txt.split("[ \t]+");
                if ( words.length == 1 ){
                    showHelp(console);
                    continue;
                }
                String command  = words[1].trim();
                showCommandHelp( console, helpMap, command );
                continue;
            }
            if ( txt.startsWith(RUN)){
                String[] words = txt.split("[ \t]+");
                if ( words.length < 1  ) continue;
                Object[] args = ZTypes.shiftArgsLeft(words);
                String fileName = String.valueOf(args[0]);
                args = ZTypes.shiftArgsLeft(args);
                try {
                    ZScript _script = new ZScript(fileName, null);
                    Function.MonadicContainer mc = _script.execute(args);
                    System.out.printf("Result : %s %n", mc.value());
                }catch (Exception e){
                    System.err.println(e);
                }
                continue;
            }

            try {
                zs = new ZScript(txt);
                zs.runContext(replContext);
                c = zs.execute();
                if ( c.isNil() ) continue;
                Object o = c.value();
                String v = ZTypes.string(o);
                String t = ZInterpret.type(o).getSimpleName() ;
                console.printf("%s // %s\n", v, t );
                history.save();
            } catch (Throwable t) {
                Throwable underlying = t.getCause();
                if ( underlying instanceof ZException ){
                    if ( underlying instanceof ZException.Parsing ) {
                        ZException.Parsing p = (ZException.Parsing) underlying;
                        console.printf("Parse Error: %s\n", p.errorMessage);
                        console.printf("Options were : %s\n", ZTypes.string(p.correctionOptions));
                        continue;
                    }
                }
                console.printf("%s\n", underlying != null ? underlying  : t );
            }
        }
    }

    public static void dance(String[] args) {
        String file = args[0];
        ZScript zs = null;
        try {
            zs = new ZScript(file, null);
            final  boolean leniency = ZTypes.bool(System.getProperty("leniency"),true);
            zs.lenient(leniency);
        }catch (Throwable t){
            if ( t.getCause() instanceof ZException.Parsing ){
                ZException.Parsing p = (ZException.Parsing)t.getCause();
                System.err.printf("Parse Error: %s\n", p.errorMessage );
                System.err.printf("Options were : %s\n", ZTypes.string(p.correctionOptions) );
            }else{
                System.err.printf("Error in parsing due to : %s\n", t.getCause() );
            }
            System.exit(2);
        }
        Object[] scripArgs = ZTypes.shiftArgsLeft(args);
        Function.MonadicContainer mc = zs.execute(scripArgs);
        if (mc.isNil()) {

        } else {
            if (mc.value() instanceof Throwable) {
                Throwable underlying = (Throwable) mc.value();
                if ( underlying instanceof ZException){
                    if ( underlying instanceof ZException.ZTerminateException ){
                        System.exit(3);
                    }
                    System.err.println(underlying);
                    zs.consumeTrace(System.err::println);
                    System.exit(4);
                }
                if ( underlying instanceof StackOverflowError ){
                    zs.consumeTrace(System.err::println);
                    System.err.println("---> Resulted in 'Stack OverFlow' Error!");
                    System.exit(4);
                }
                underlying.printStackTrace();
                System.exit(1);
            }
        }
        System.exit(0);
    }

    public static void main(String[] args) throws Exception {
        if (args.length == 0) {
            stepDance(null);
        } else {
            dance(args);
        }
    }

    private static String getBuildVersionAndTime() {
        final String result = new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream("/version.txt"))).
                lines().parallel().collect(Collectors.joining("\n"));
        return result.trim();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy