diff options
-rw-r--r-- | sources/scala/Option.scala | 19 | ||||
-rw-r--r-- | sources/scala/tools/scalap/Arguments.scala | 192 | ||||
-rw-r--r-- | sources/scala/tools/scalap/Main.scala | 79 |
3 files changed, 258 insertions, 32 deletions
diff --git a/sources/scala/Option.scala b/sources/scala/Option.scala index b037a3ef04..25030ab578 100644 --- a/sources/scala/Option.scala +++ b/sources/scala/Option.scala @@ -25,37 +25,42 @@ trait Option[+A] extends Iterable[A] { case _ => false } - def get: A = this match { + def get: A = match { case None => error("None.get") case Some(x) => x } - def map[B](f: A => B): Option[B] = this match { + def get[B >: A](default: B): B = match { + case None => default + case Some(x) => x + } + + def map[B](f: A => B): Option[B] = match { case None => None case Some(x) => Some(f(x)) } - def flatMap[B](f: A => Option[B]): Option[B] = this match { + def flatMap[B](f: A => Option[B]): Option[B] = match { case None => None case Some(x) => f(x) } - def filter(p: A => Boolean): Option[A] = this match { + def filter(p: A => Boolean): Option[A] = match { case None => None case Some(x) => if (p(x)) Some(x) else None } - def foreach(f: A => Unit): Unit = this match { + def foreach(f: A => Unit): Unit = match { case None => () case Some(x) => f(x) } - def elements: Iterator[A] = this match { + def elements: Iterator[A] = match { case None => Iterator.empty case Some(x) => Iterator.fromSeq(x) } - def toList: List[A] = this match { + def toList: List[A] = match { case None => Predef.List() case Some(x) => Predef.List(x) } diff --git a/sources/scala/tools/scalap/Arguments.scala b/sources/scala/tools/scalap/Arguments.scala new file mode 100644 index 0000000000..f8e0cb29a5 --- /dev/null +++ b/sources/scala/tools/scalap/Arguments.scala @@ -0,0 +1,192 @@ +package scalap; + +import scala.collection._; + + +object Arguments { + + case class Parser(optionPrefix: Char) { + + val options = new mutable.JavaSetAdaptor[String](new java.util.HashSet()); + val prefixes = new mutable.JavaSetAdaptor[String](new java.util.HashSet()); + val optionalArgs = new mutable.JavaSetAdaptor[String](new java.util.HashSet()); + val prefixedBindings = new mutable.JavaMapAdaptor[String, Char](new java.util.HashMap()); + val optionalBindings = new mutable.JavaMapAdaptor[String, Char](new java.util.HashMap()); + + def error(message: String): Unit = Console.println(message); + + def withOption(option: String): Parser = { + options += option; + this + } + + def withOptionalArg(option: String): Parser = { + optionalArgs += option; + this + } + + def withOptionalBinding(option: String, separator: Char): Parser = { + optionalBindings(option) = separator; + this + } + + def withPrefixedArg(prefix: String): Parser = { + prefixes += prefix; + this + } + + def withPrefixedBinding(prefix: String, separator: Char): Parser = { + prefixedBindings(prefix) = separator; + this + } + + def parseBinding(str: String, separator: Char): Pair[String, String] = { + val eqls = str.indexOf(separator); + if (eqls < 0) { + error("missing '" + separator + "' in binding '" + str + "'"); + Pair("", "") + } else + Pair(str.substring(0, eqls).trim(), + str.substring(eqls + 1).trim()); + } + + def parse(args: Array[String]): Arguments = { + val res = new Arguments; + parse(args, res); + res + } + + def parse(args: Array[String], res: Arguments): Unit = { + if (args != null) { + var i = 0; + while (i < args.length) + if ((args(i) == null) || (args(i).length() == 0)) + i = i + 1; + else if (args(i).charAt(0) != optionPrefix) { + res.addOther(args(i)); + i = i + 1; + } else if (options contains args(i)) { + res.addOption(args(i)); + i = i + 1; + } else if (optionalArgs contains args(i)) { + if ((i + 1) == args.length) { + error("missing argument for '" + args(i) + "'"); + i = i + 1; + } else { + res.addArgument(args(i), args(i + 1)); + i = i + 2; + } + } else if (optionalBindings contains args(i)) { + if ((i + 1) == args.length) { + error("missing argument for '" + args(i) + "'"); + i = i + 1; + } else { + res.addBinding(args(i), + parseBinding(args(i + 1), optionalBindings(args(i)))); + i = i + 2; + } + } else { + var iter = prefixes.elements; + val j = i; + while ((i == j) && iter.hasNext) { + val prefix = iter.next; + if (args(i) startsWith prefix) { + res.addPrefixed(prefix, args(i).substring(prefix.length()).trim()); + i = i + 1; + } + } + if (i == j) { + val iter = prefixedBindings.keys; + while ((i == j) && iter.hasNext) { + val prefix = iter.next; + if (args(i) startsWith prefix) { + val arg = args(i).substring(prefix.length()).trim(); + i = i + 1; + res.addBinding(prefix, + parseBinding(arg, prefixedBindings(prefix))); + } + } + if (i == j) { + error("unknown option '" + args(i) + "'"); + i = i + 1; + } + } + } + } + } + } + + def parse(options: String*)(args: Array[String]): Arguments = { + val parser = new Parser('-'); + val iter = options.elements; + while (iter.hasNext) + parser withOption iter.next; + parser.parse(args) + } +} + +class Arguments { + + private val options: mutable.Set[String] = new mutable.JavaSetAdaptor(new java.util.HashSet()); + private val arguments: mutable.Map[String, String] = new mutable.JavaMapAdaptor(new java.util.HashMap()); + private val prefixes: mutable.Map[String, mutable.Set[String]] = new mutable.JavaMapAdaptor(new java.util.HashMap()); + private val bindings: mutable.Map[String, mutable.Map[String, String]] = new mutable.JavaMapAdaptor(new java.util.HashMap()); + private val others: mutable.Buffer[String] = new mutable.Buffer; + + def addOption(option: String): Unit = options += option; + + def addArgument(option: String, arg: String): Unit = arguments(option) = arg; + + def addPrefixed(prefix: String, arg: String): Unit = + if (prefixes isDefinedAt prefix) + prefixes(prefix) += arg; + else { + prefixes(prefix) = new mutable.JavaSetAdaptor(new java.util.HashSet()); + prefixes(prefix) += arg; + }; + + def addBinding(tag: String, key: String, value: String): Unit = + if (key.length() > 0) { + if (bindings isDefinedAt tag) + bindings(tag)(key) = value; + else { + bindings(tag) = new mutable.JavaMapAdaptor(new java.util.HashMap()); + bindings(tag)(key) = value; + } + }; + + def addBinding(tag: String, binding: Pair[String, String]): Unit = + addBinding(tag, binding._1, binding._2); + + def addOther(arg: String): Unit = others += arg; + + def contains(option: String): Boolean = options contains option; + + def getArgument(option: String): Option[String] = arguments get option; + + def getSuffixes(prefix: String): Set[String] = + prefixes.get(prefix).match { + case None => new mutable.JavaSetAdaptor(new java.util.HashSet()); + case Some(set) => set + } + + def containsSuffix(prefix: String, suffix: String): Boolean = + prefixes.get(prefix).match { + case None => false + case Some(set) => set contains suffix + }; + + def getBindings(tag: String): Map[String, String] = + bindings.get(tag).match { + case None => new mutable.JavaMapAdaptor(new java.util.HashMap()); + case Some(map) => map + } + + def getBinding(option: String, key: String): Option[String] = + bindings.get(option).match { + case None => None + case Some(map) => map get key + }; + + def getOthers: List[String] = others.toList; +} diff --git a/sources/scala/tools/scalap/Main.scala b/sources/scala/tools/scalap/Main.scala index 052df7f83d..4da32f5f67 100644 --- a/sources/scala/tools/scalap/Main.scala +++ b/sources/scala/tools/scalap/Main.scala @@ -14,38 +14,67 @@ import scala.collection._; object Main { + val VERSION = "1.0a"; + + var verbose = false; + def usage: Unit = { - Console.println("usage: scalap <name>"); + Console.println("usage: scalap {<option>} <name>"); + Console.println("where <option> is"); + Console.println(" -verbose print out additional information"); + Console.println(" -version print out the version number of scalap"); + Console.println(" -classpath <path> set the classpath"); + } + + def process(path: ClassPath)(classname: String): Unit = { + val file = path.openClass(Names.encode(classname)); + if (file.exists) { + if (verbose) + Console.println(Console.BOLD + "FILENAME" + Console.RESET + + " = " + file.getPath); + val reader = new ByteArrayReader(file.content); + val clazz = new Classfile(reader); + val attrib = clazz.attribs.find(a => a.toString() == "ScalaSignature"); + attrib match { + case Some(a) => + val info = new ScalaAttribute(a.reader); + //Console.println("read attribute"); + val symtab = new EntityTable(info); + //Console.println("read entities"); + //symtab.print; + val out = new OutputStreamWriter(System.out); + val writer = new ScalaWriter(out); + symtab.root.elements foreach ( + sym => { writer.printSymbol(sym); + writer.println*; }); + out.flush(); + case None => + Console.println("Java classes not supported yet."); + } + } else + Console.println("class/object not found."); } def main(args: Array[String]) = { if (args.length == 0) usage; else { - val path = new ClassPath; - val file = path.openClass(Names.encode(args(0))); - if (file.exists) { - val reader = new ByteArrayReader(file.content); - val clazz = new Classfile(reader); - val attrib = clazz.attribs.find(a => a.toString() == "ScalaSignature"); - attrib match { - case Some(a) => - val info = new ScalaAttribute(a.reader); - //Console.println("read attribute"); - val symtab = new EntityTable(info); - //Console.println("read entities"); - //symtab.print; - val out = new OutputStreamWriter(System.out); - val writer = new ScalaWriter(out); - symtab.root.elements foreach ( - sym => { writer.printSymbol(sym); - writer.println*; }); - out.flush(); - case None => - Console.println("Java classes not supported yet."); - } - } else - Console.println("class/object not found."); + val arguments = Arguments.Parser('-') + .withOption("-verbose") + .withOption("-version") + .withOptionalArg("-classpath") + .parse(args); + if (arguments contains "-version") + Console.println("scalap " + VERSION); + verbose = arguments contains "-verbose"; + val path = arguments.getArgument("-classpath") match { + case None => new ClassPath + case Some(path) => new ClassPath { override val classPath = path } + } + if (verbose) + Console.println(Console.BOLD + "CLASSPATH" + Console.RESET + + " = " + path); + arguments.getOthers.foreach(process(path)); } } } |