package org.jerlang.erts; import java.util.HashMap; import org.jerlang.FunctionSignature; import org.jerlang.erts.emulator.EmulatorFlag; import org.jerlang.erts.emulator.InitFlag; import org.jerlang.erts.erlang.Error; import org.jerlang.stdlib.Lists; import org.jerlang.stdlib.Shell; import org.jerlang.type.Atom; import org.jerlang.type.Integer; import org.jerlang.type.List; import org.jerlang.type.Str; /** * The erl program starts an Erlang runtime system. * * http://erlang.org/doc/man/erl.html */ public class Emulator { private static final Atom unsupported_option = Atom.of("unsupported_option"); private static final HashMap<Atom, List> userFlags = Runtime.userFlags(); public static void main(String[] args) { parse(args); Shell.start(); } public static void parse(String[] args) { for (int index = 0; index < args.length; index++) { String arg = args[index]; if (Runtime.extraFlag()) { Runtime.addPlainArgument(arg); } else if (InitFlag.valid(arg)) { index = parseInitFlag(InitFlag.of(arg), args, index); } else if (EmulatorFlag.valid(arg)) { index = parseEmulatorFlag(EmulatorFlag.of(arg), args, index); } else { // User flag if (!arg.startsWith("-") || arg.length() < 2) { throw new Error("Invalid user flag: " + arg); } Atom userFlag = Atom.of(arg.substring(1)); List flagList = List.nil; while (index + 1 < args.length && !args[index + 1].startsWith("-")) { flagList = new List(Str.of(args[++index]), flagList); } flagList = Lists.reverse(flagList); if (!userFlags.containsKey(userFlag)) { userFlags.put(userFlag, List.nil); } List newList = Lists.reverse(new List(flagList, userFlags.get(userFlag))); userFlags.put(userFlag, newList); } } } private static int parseEmulatorFlag(EmulatorFlag flag, String[] args, int index) { switch (flag) { case RELEASE: case WARNING: // TODO return index + 1; default: throw new Error("Unsupported emulator flag: " + flag); } } private static int parseInitFlag(InitFlag flag, String[] args, int index) { switch (flag) { case EXTRA: Runtime.setExtraFlag(); return index; case RUN: case S: return parseRunFlag(args, index); case SNAME: // TODO return index + 1; default: throw new Error("Unsupported init flag: " + flag); } } private static int parseRunFlag(String[] args, int index) { Atom mod = Atom.of(args[++index]); Atom func = Atom.of("start"); if (index < args.length) { if (args[index + 1].startsWith("-")) { Runtime.setRunFlag(new FunctionSignature(mod, func, Integer.ZERO)); return index; } func = Atom.of(args[++index]); } List arguments = List.nil; while (++index < args.length) { arguments = new List(Str.of(args[index]), arguments); } arguments = Lists.reverse(arguments); Integer arity = Erlang.length(arguments); Runtime.setRunFlag(new FunctionSignature(mod, func, arity)); return index; } }