# HG changeset patch # User Anders Johnsen # Date 1218564455 -7200 # Node ID 9e9f3e7e342b4b429ad9b042c7000cd9ea847392 # Parent f4149d4f689678d2affd28d0ad4f7b184c30cb2e Added dang folder and Module in ast. diff -r f4149d4f6896 -r 9e9f3e7e342b dang/OptParse.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dang/OptParse.d Tue Aug 12 20:07:35 2008 +0200 @@ -0,0 +1,810 @@ +/* +Copyright (c) 2007 Kirk McDonald + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +/** + * Command-line option parsing, in the style of Python's optparse. + * + * Refer to the complete docs for more information. + */ +module dang.OptParse; + +import tango.io.Stdout; +import tango.text.Util : locate, locatePrior; +import tango.text.Ascii : toUpper; +import tango.stdc.stdlib : exit, EXIT_FAILURE, EXIT_SUCCESS; +import tango.text.convert.Integer : parse, toInt, toString = toString; +import tango.text.convert.Utf : toString, toString32; + +/* +Options may be in two forms: long and short. Short options start with a single +dash and are one letter long. Long options start with two dashes and may +consist of any number of characters (so long as they don't start with a dash, +though they may contain dashes). Options are case-sensitive. + +Short options may be combined. The following are equivalent: + +$ myapp -a -b -c +$ myapp -abc +$ myapp -ab -c + +If -f and --file are aliases of the same option, which accepts an argument, +the following are equivalent: + +$ myapp -f somefile.txt +$ myapp -fsomefile.txt +$ myapp --file somefile.txt +$ myapp --file=somefile.txt + +The following are also valid: + +$ myapp -abcf somefile.txt +$ myapp -abcfsomefile.txt +$ myapp -abc --file somefile.txt + +If an option occurs multiple times, the last one is the one recorded: + +$ myapp -f somefile.txt --file otherfile.txt + +Matches 'otherfile.txt'. +*/ + +bool startswith(char[] s, char[] start) { + if (s.length < start.length) return false; + return s[0 .. start.length] == start; +} +bool endswith(char[] s, char[] end) { + if (s.length < end.length) return false; + return s[$ - end.length .. $] == end; +} + +/// Thrown if client code tries to set up an improper option. +class OptionError : Exception { + this(char[] msg) { super(msg); } +} +// Thrown if client code tries to extract the wrong type from an option. +class OptionTypeError : Exception { + this(char[] msg) { super(msg); } +} + +/++ +This class represents the results after parsing the command-line. ++/ +class Options { + char[][][char[]] opts; + int[char[]] counted_opts; + /// By default, leftover arguments are placed in this array. + char[][] args; + + /// Retrieves the results of the Store and StoreConst actions. + char[] opIndex(char[] opt) { + char[][]* o = opt in opts; + if (o) { + return (*o)[0]; + } else { + return ""; + } + } + /// Retrieves the results of the Store action, when the type is Integer. + int value(char[] opt) { + char[][]* o = opt in opts; + if (o) { + return toInt((*o)[0]); + } else { + return 0; + } + } + /// Retrieves the results of the Append and AppendConst actions. + char[][] list(char[] opt) { + char[][]* o = opt in opts; + if (o) { + return *o; + } else { + return null; + } + } + /// Retrieves the results of the Append action, when the type is Integer. + int[] valueList(char[] opt) { + char[][]* o = opt in opts; + int[] l; + if (o) { + l.length = (*o).length; + foreach (i, s; *o) { + l[i] = toInt(s); + } + } + return l; + } + /// Retrieves the results of the Count action. + int count(char[] opt) { + int* c = opt in counted_opts; + if (c) { + return *c; + } else { + return 0; + } + } + /// Retrieves the results of the SetTrue and SetFalse actions. + bool flag(char[] opt) { + char[][]* o = opt in opts; + if (o) { + return (*o)[0] == "1"; + } else { + return false; + } + } +} + +// Options, args, this opt's index in args, name[, arg] +/// +alias void delegate(Options, inout char[][], inout int, char[], char[]) OptionCallbackFancyArg; +/// +alias void delegate(Options, inout char[][], inout int, char[], int) OptionCallbackFancyInt; +/// +alias void delegate(Options, inout char[][], inout int, char[]) OptionCallbackFancy; + +/// +alias void delegate(char[]) OptionCallbackArg; +/// +alias void delegate(int) OptionCallbackInt; +/// +alias void delegate() OptionCallback; + +/* +Actions: + * Store: name + * StoreConst: name, const_value + * Append: name + * AppendConst: name, const_value + * Count: name + * CallbackArg: dga + * CallbackVoid: dg +*/ +/// +enum Action { /+++/Store, /+++/StoreConst, /+++/Append, /+++/AppendConst, /+++/Count, /+++/SetTrue, /+++/SetFalse, /+++/Callback, /+++/CallbackFancy, /+++/Help /+++/} +/// +enum ArgType { /+++/None, /+++/String, /+++/Integer /+++/} + +ArgType defaultType(Action action) { + switch (action) { + case Action.Store, Action.Append, Action.Callback, Action.CallbackFancy: + return ArgType.String; + break; + default: + return ArgType.None; + break; + } +} + +/++ +This class represents a single command-line option. ++/ +class Option { + char[][] shortopts, longopts; + Action action; + ArgType type; + char[] name, argname; + char[] const_value; + + char[] default_string; + int default_value; + bool default_flag, has_default; + + OptionCallbackArg callback; + OptionCallbackInt int_callback; + OptionCallback void_callback; + + OptionCallbackFancyArg fancy_callback; + OptionCallbackFancyInt fancy_int_callback; + OptionCallbackFancy fancy_void_callback; + char[] helptext; + this( + char[][] shorts, char[][] longs, ArgType type, + Action act, char[] name, char[] const_value, + OptionCallbackArg dga, OptionCallback dg, + OptionCallbackInt dgi, + OptionCallbackFancyArg fdga, + OptionCallbackFancyInt fdgi, + OptionCallbackFancy fdg + ) { + this.shortopts = shorts; + this.longopts = longs; + this.action = act; + this.type = type; + this.name = name; + this.argname = toUpper(name.dup); + this.default_string = ""; + this.default_value = 0; + this.default_flag = false; + + // Perform sanity checks. + assert (name !is null); + switch (act) { + case Action.Store, Action.Append: + assert(type != ArgType.None); + break; + case Action.StoreConst, Action.AppendConst: + assert(type == ArgType.None); + assert(const_value !is null); + break; + case Action.Callback: + //assert(type != ArgType.None); + switch (type) { + case ArgType.String: + assert(dga !is null); + break; + case ArgType.Integer: + assert(dgi !is null); + break; + case ArgType.None: + assert(dg !is null); + break; + } + break; + case Action.CallbackFancy: + switch (type) { + case ArgType.String: + assert(fdga !is null); + break; + case ArgType.Integer: + assert(fdgi !is null); + break; + case ArgType.None: + assert(fdg !is null); + break; + } + default: + break; + } + this.const_value = const_value; + this.callback = dga; + this.int_callback = dgi; + this.void_callback = dg; + this.fancy_callback = fdga; + this.fancy_int_callback = fdgi; + this.fancy_void_callback = fdg; + } + char[] toString() { + int optCount = this.shortopts.length + this.longopts.length; + char[] result; + bool printed_arg = false; + foreach(i, opt; this.shortopts ~ this.longopts) { + result ~= opt; + if (i < optCount-1) { + result ~= ", "; + } else if (this.hasArg()) { + result ~= "=" ~ toUpper(this.argname.dup); + } + } + return result; + } + //enum Action { Store, StoreConst, Append, AppendConst, Count, SetTrue, SetFalse, Callback, CallbackFancy, Help } + void issue_default(Options results) { + // Only set the default if the option doesn't already have a value. + char[][]* val = this.name in results.opts; + switch (this.action) { + case Action.Store, Action.Append: + if (val !is null) return; + if (this.type == ArgType.String) { + results.opts[name] = [default_string]; + } else { + results.opts[name] = [.toString(default_value)]; + } + break; + case Action.StoreConst, Action.AppendConst: + if (val !is null) return; + results.opts[name] = [default_string]; + break; + case Action.SetTrue, Action.SetFalse: + if (val !is null) return; + if (default_flag) { + results.opts[name] = ["1"]; + } else { + results.opts[name] = ["0"]; + } + break; + default: + return; + } + } + // Does whatever this option is supposed to do. + void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { + int i; + if (this.type == ArgType.Integer) { + // Verify that it's an int. + i = parser.toOptInt(arg); + } + switch (this.action) { + case Action.Store: + results.opts[name] = [arg]; + break; + case Action.Append: + results.opts[name] ~= arg; + break; + case Action.StoreConst: + assert(arg is null, "Got unexpected argument for '"~name~"' option."); + results.opts[name] = [const_value]; + break; + case Action.AppendConst: + assert(arg is null, "Got unexpected argument for '"~name~"' option."); + results.opts[name] ~= const_value; + break; + case Action.Count: + assert(arg is null, "Got unexpected argument for '"~name~"' option."); + ++results.counted_opts[name]; + break; + case Action.SetTrue: + results.opts[name] = ["1"]; + break; + case Action.SetFalse: + results.opts[name] = ["0"]; + break; + case Action.Callback: + switch (type) { + case ArgType.String: + callback(arg); + break; + case ArgType.Integer: + int_callback(i); + break; + case ArgType.None: + void_callback(); + break; + } + break; + case Action.CallbackFancy: + switch (type) { + case ArgType.String: + fancy_callback(results, args, idx, name, arg); + break; + case ArgType.Integer: + fancy_int_callback(results, args, idx, name, i); + break; + case ArgType.None: + fancy_void_callback(results, args, idx, name); + break; + } + break; + case Action.Help: + parser.helpText(); + exit(EXIT_SUCCESS); + break; + } + } + /// Returns whether this option accepts an argument. + bool hasArg() { + return this.type != ArgType.None; + } + /// Sets the help text for this option. + Option help(char[] help) { + this.helptext = help; + return this; + } + /// Sets the name of this option's argument, if it has one. + Option argName(char[] argname) { + this.argname = argname; + return this; + } + Option def(char[] val) { + if ( + (this.type != ArgType.String || (this.action != Action.Store && this.action != Action.Append)) && + this.action != Action.StoreConst && this.action != Action.AppendConst + ) + throw new OptionError("Cannot specify string default for non-string option '"~this.name~"'"); + this.has_default = true; + this.default_string = val; + return this; + } + Option def(int val) { + if (this.type != ArgType.Integer || (this.action != Action.Store && this.action != Action.Append)) + throw new OptionError("Cannot specify integer default for non-integer option '"~this.name~"'"); + this.has_default = true; + this.default_value = val; + return this; + } + Option def(bool val) { + if (this.action != Action.SetTrue && this.action != Action.SetFalse) + throw new OptionError("Cannot specify boolean default for non-flag option '"~this.name~"'"); + this.has_default = true; + this.default_flag = val; + return this; + } + // Returns true if the passed option string matches this option. + bool matches(char[] _arg) { + dchar[] arg = toString32(_arg); + if ( + arg.length < 2 || + arg.length == 2 && (arg[0] != '-' || arg[1] == '-') || + arg.length > 2 && (arg[0 .. 2] != "--" || arg[2] == '-') + ) { + return false; + } + if (arg.length == 2) { + foreach (opt; shortopts) { + if (_arg == opt) { + return true; + } + } + } else { + foreach (opt; longopts) { + if (_arg == opt) { + return true; + } + } + } + return false; + } +} + +/++ +This class is used to define a set of options, and parse the command-line +arguments. ++/ +class OptionParser { + OptionCallbackArg leftover_cb; + /// An array of all of the options known by this parser. + Option[] options; + char[] name, desc; + /// The description of the programs arguments, as used in the Help action. + char[] argdesc; + private void delegate(char[]) error_callback; + + this(char[] desc="") { + this.name = ""; + this.desc = desc; + this.argdesc = "[options] args..."; + } + + /// Sets a callback, to override the default error behavior. + void setErrorCallback(void delegate(char[]) dg) { + error_callback = dg; + } + void unknownOptError(char[] opt) { + error("Unknown argument '"~opt~"'"); + } + void expectedArgError(char[] opt) { + error("'"~opt~"' option expects an argument."); + } + /// Displays an error message and terminates the program. + void error(char[] err) { + if (error_callback !is null) { + error_callback(err); + } else { + this.helpText(); + Stdout.formatln(err); + } + exit(EXIT_FAILURE); + } + int toOptInt(char[] s) { + int i; + uint ate; + i = .parse(s, 10u, &ate); + if (ate != s.length) + error("Could not convert '"~s~"' to an integer."); + return i; + } + + /// Displays useful "help" information about the program's options. + void helpText() { + int optWidth; + char[][] optStrs; + typedef char spacechar = ' '; + spacechar[] padding; + // Calculate the maximum width of the option lists. + foreach(i, opt; options) { + optStrs ~= opt.toString(); + if (optStrs[i].length > optWidth) { + optWidth = optStrs[i].length; + } + } + Stdout.formatln("Usage: {0} {1}", this.name, this.argdesc); + if (this.desc !is null && this.desc != "") Stdout.formatln(this.desc); + Stdout.formatln("\nOptions:"); + foreach(i, opt; options) { + padding.length = optWidth - optStrs[i].length; + Stdout.formatln(" {0}{1} {2}", optStrs[i], cast(char[])padding, opt.helptext); + } + } + + // Checks the passed arg against all the options in the parser. + // Returns null if no match is found. + Option matches(char[] arg) { + foreach(o; options) { + if (o.matches(arg)) { + return o; + } + } + return null; + } + char[] getBaseName(char[] path) { + version(Windows) { + char delimiter = '\\'; + } else { + char delimiter = '/'; + } + uint idx = locatePrior(path, delimiter); + if (idx == path.length) return path; + return path[idx+1 .. $]; + } + char[] getProgramName(char[] path) { + version(Windows) { + // (Unicode note: ".exe" only contains 4 code units, so this slice + // should Just Work.) (Although it remains to be seen how robust + // this code actually is.) + //Stdout.formatln(path); + //assert(path[$-4 .. $] == ".exe"); + //path = path[0 .. $-4]; + } + return getBaseName(path); + } + /// Parses the passed command-line arguments and returns the results. + Options parse(char[][] args) { + this.name = getProgramName(args[0]); + args = args[1 .. $]; + Options options = new Options; + /* + The issue is this: + + $ myapp -abc + + This might be three short opts, or one or two opts, the last of which + accepts an argument. In the three-opt case, we want to get: + + $ myapp -a -b -c + + In the one-opt case, we want: + + $ myapp -a bc + + In the two-opt case, we want: + + $ myapp -a -b c + + We also want to parse apart "--file=somefile" into "--file somefile" + */ + char[] opt, newopt, arg; + dchar[] opt32; + int idx; + Option match; + + for (int i=0; i= 2) { + opt32 = toString32(opt[1 .. $]); + foreach (j, c; opt32) { + newopt = .toString("-" ~ [c]); + match = matches(newopt); + if (match is null) { + unknownOptError(newopt); + } + if (match.hasArg) { + // This is the last char in the group, look to the + // next element of args for the arg. + if (j == opt32.length-1) { + if (i == args.length-1) expectedArgError(match.name); + arg = args[i+1]; + ++i; + // Otherwise, consume the rest of this group for + // the arg. + } else { + arg = .toString(opt32[j+1 .. $]); + match.performAction(this, options, args, i, arg); + break; + } + } else { + arg = null; + } + match.performAction(this, options, args, i, arg); + } + } else { + unknownOptError(opt); + } + } else { + if (this.leftover_cb is null) { + options.args ~= opt; + } else { + this.leftover_cb(opt); + } + } + } + foreach (o; this.options) { + o.issue_default(options); + } + return options; + } + + /++ + Overrides the default behavior of leftover arguments, calling this callback + with them instead of adding them an array. + +/ + void leftoverCallback(OptionCallbackArg dg) { + this.leftover_cb = dg; + } + /// + Option addOption(Option option) { + this.options ~= option; + return option; + } + // options action name type const_value dga dgv dgi fdga fdgi fdg + /// + Option addOption(char[][] options ...) { + return addOption(options, Action.Store, null, defaultType(Action.Store), null, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, char[] name) { + return addOption(options, Action.Store, name, defaultType(Action.Store), null, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, Action action) { + return addOption(options, action, null, defaultType(action), null, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, ArgType type) { + return addOption(options, Action.Store, null, type, null, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, Action action, ArgType type) { + return addOption(options, action, null, type, null, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, char[] name, Action action) { + return addOption(options, action, name, defaultType(action), null, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, char[] name, Action action, ArgType type) { + return addOption(options, action, name, type, null, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, Action action, char[] const_value) { + return addOption(options, action, null, defaultType(action), const_value, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, char[] name, char[] const_value) { + return addOption(options, Action.StoreConst, name, defaultType(Action.Store), const_value, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, char[] name, Action action, char[] const_value) { + return addOption(options, action, name, defaultType(action), const_value, null, null, null, null, null, null); + } + /// + Option addOption(char[][] options, OptionCallbackArg dg) { + return addOption(options, Action.Callback, null, ArgType.String, null, dg, null, null, null, null, null); + } + /// + Option addOption(char[][] options, OptionCallback dg) { + return addOption(options, Action.Callback, null, ArgType.None, null, null, dg, null, null, null, null); + } + /// + Option addOption(char[][] options, OptionCallbackInt dg) { + return addOption(options, Action.Callback, null, ArgType.Integer, null, null, null, dg, null, null, null); + } + /// + Option addOption(char[][] options, OptionCallbackFancyArg dg) { + return addOption(options, Action.CallbackFancy, null, ArgType.String, null, null, null, null, dg, null, null); + } + /// + Option addOption(char[][] options, OptionCallbackFancy dg) { + return addOption(options, Action.CallbackFancy, null, ArgType.None, null, null, null, null, null, null, dg); + } + /// + Option addOption(char[][] options, OptionCallbackFancyInt dg) { + return addOption(options, Action.CallbackFancy, null, ArgType.Integer, null, null, null, null, null, dg, null); + } + /// + Option addOption(char[][] options, char[] name, OptionCallbackFancyArg dg) { + return addOption(options, Action.CallbackFancy, name, ArgType.String, null, null, null, null, dg, null, null); + } + /// + Option addOption(char[][] options, char[] name, OptionCallbackFancy dg) { + return addOption(options, Action.CallbackFancy, name, ArgType.None, null, null, null, null, null, null, dg); + } + /// + Option addOption(char[][] options, char[] name, OptionCallbackFancyInt dg) { + return addOption(options, Action.CallbackFancy, name, ArgType.Integer, null, null, null, null, null, dg, null); + } + // Although users certainly /can/ call this, all those overloads are there + // for a reason. + Option addOption( + char[][] options, + Action action, char[] name, ArgType type, char[] const_value, + OptionCallbackArg callback, OptionCallback vcall, + OptionCallbackInt icall, + OptionCallbackFancyArg fdga, + OptionCallbackFancyInt fdgi, + OptionCallbackFancy fdg + ) { + char[][] shortopts; + char[][] longopts; + dchar[] opt; + Option option; + foreach (_opt; options) { + // (Unicode note: We convert to dchar[] so the length checks work + // out in the event of a short opt with a >127 character.) + opt = toString32(_opt); + if (opt.length < 2) { + throw new OptionError( + "invalid option string '" ~ _opt ~ "': must be at least two characters long" + ); + } else if (opt.length > 2) { + if (opt[0 .. 2] != "--" || opt[2] == '-') + throw new OptionError( + "invalid long option string '" ~ _opt ~ "': must start with --, followed by non-dash" + ); + longopts ~= _opt; + } else { + if (opt[0] != '-' || opt[1] == '-') + throw new OptionError( + "invalid short option string '" ~ _opt ~ "': must be of the form -x, where x is non-dash" + ); + shortopts ~= _opt; + } + } + if (name is null) { + // (Unicode note: We know '-' is a single code unit, so these + // slices are okay.) + if (longopts.length > 0) + name = longopts[0][2 .. $]; + else if (shortopts.length > 0) + name = shortopts[0][1 .. 2]; + else + throw new OptionError( + "No options provided to addOption!" + ); + } + option = new Option(shortopts, longopts, type, action, name, const_value, callback, vcall, icall, fdga, fdgi, fdg); + this.options ~= option; + return option; + } +} + diff -r f4149d4f6896 -r 9e9f3e7e342b dang/compiler.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dang/compiler.d Tue Aug 12 20:07:35 2008 +0200 @@ -0,0 +1,240 @@ +module dang.compiler; + +import tango.io.Stdout, + tango.core.Signal, + tango.core.Memory, + tango.sys.Process, + tango.time.StopWatch, + tango.text.Util, + tango.io.FileConduit, + tango.io.FilePath; + +import lexer.Lexer, + parser.Action, + parser.Parser; + +import basic.SourceManager; + +import basic.Message; + +import ast.Module; + +import tango.stdc.posix.unistd; +import tango.stdc.stdlib; + +import Opt = dang.OptParse; + +class NullAction : Action +{ +} + +void checkFiles(char[][] *files) +{ +// GC.disable(); + bool non_existant_files = false; + bool duplicate_files = false; + + char[][] validFiles; + + foreach (file; *files) + { + scope path = new FilePath(file); + + if (!path.exists) + { + Stderr.formatln("'{}' does not exist", file).newline; + non_existant_files = true; + + continue; + } + + bool fileInStack = false; + foreach (vFile; validFiles) + if (vFile == file) + { + fileInStack = true; + duplicate_files = true; + } + + if (fileInStack) + continue; + + validFiles ~= path.toString(); + } + + *files = validFiles; + + if (non_existant_files) + throw new Exception("All files given must exist"); + if (duplicate_files) + Stderr("warning: duplicate files ignored").newline; +} + +void main(char[][] args) +{ + char[][] filesToHandle; + + Signal!(char[][]*) preStart; + + Signal!(char[]) preLex; + Signal!(Lexer) postLex; + + Signal!(Lexer) preParse; + Signal!(Module[], SourceManager) postParse; + Signal!(Module[], SourceManager) postSema; + + preStart.attach(&checkFiles); + + auto argParse = new Opt.OptionParser(`Dang "D" compiler v0.1`); + + bool optimize = false; + bool inline = false; + + + SourceManager src_mgr = new SourceManager; + MessageHandler messages = new MessageHandler(src_mgr); + + argParse.addOption(["-h", "--help"], Opt.Action.Help) + .help("Show this help message"); + + auto options = argParse.parse(args); + + filesToHandle ~= options.args; + + // Will throw exception if some files don't exist + preStart(&filesToHandle); + + struct Measurement { char[] label; double time; } + Measurement[] timings; + StopWatch total; + total.start; + + Module[] modules; + + StopWatch watch; + watch.start; + foreach (file; filesToHandle) + { + preLex(file); + + auto start = src_mgr.addFile(file); + auto lexer = new Lexer(start, src_mgr, messages); + postLex(lexer); + + preParse(lexer); + + auto parser = new Parser(messages); + auto action = new NullAction; + modules ~= cast(Module)parser.parse(src_mgr, lexer, action); + timings ~= Measurement("Lex + Parse of '"~file~"'", watch.stop); + messages.checkErrors(ExitLevel.Parser); +/* + StopWatch watch2; + watch.start; + watch2.start; + Module[] mods = (new LoadModule).visit(m, src_mgr, messages); + (new ScopeBuilder).visit(m); + auto scope_builder = watch2.stop; + watch2.start; + (new ScopeCheck).visit(m); + auto scope_check = watch2.stop; + watch2.start; + (new TypeCheck).visit(m); + auto type_check = watch2.stop; + watch2.start; + + foreach (decl; m.decls) + decl.simplify(); + auto simplify = watch2.stop; + auto extra_stuff = watch.stop; + timings ~= Measurement("Extra stuff", watch.stop); + timings ~= Measurement(" - Building scopes", scope_builder); + timings ~= Measurement(" - Checking scopes", scope_check); + timings ~= Measurement(" - Checking types", type_check); + + postParse(m, src_mgr);*/ + } +/* + (new LiteralInterpreter(messages)).visit(modules); + messages.checkErrors; + postParse(modules, src_mgr); + + class ModuleLoader : Visitor!(void) + { + Module[] visit(Module[] modules, MessageHandler messages, SourceManager src_mgr) + { + this.modules = modules; + this.messages = messages; + this.src_mgr = src_mgr; + super.visit(modules); + return this.modules; + } + + override void visitImportDecl(ImportDecl decl) + { + char[] path = replace!(char)(decl.get,'.','/')~".d"; + + auto start = src_mgr.addFile(path); + auto lexer = new Lexer(start, src_mgr, messages); + + auto parser = new Parser(messages); + auto action = new AstAction(src_mgr); + + Module m = cast(Module)parser.parse(src_mgr, lexer, action); + modules ~= m; + m.outputModule = false; + // decl.env.mHandle.add(m); + messages.checkErrors(ExitLevel.Parser); + } + + Module[] modules; + SourceManager src_mgr; + MessageHandler messages; + } + + modules = (new ModuleLoader()).visit(modules, messages, src_mgr); + messages.checkErrors; + + (new BuildScopes).visit(modules); + (new BuildSymbols).visit(modules); + StopWatch watch2; + watch.start; + watch2.start; + + (new BuildTypes(messages)).visit(modules); + + (new CheckScopes(messages)).visit(modules); + messages.checkErrors; + auto scope_check = watch2.stop; + + watch2.start; + (new CheckTypes(messages)).visit(modules); + messages.checkErrors; + auto type_check = watch2.stop; + + watch2.start; + (new ObjectOriented(messages)).visit(modules); + messages.checkErrors; + auto object_check = watch2.stop; + + watch2.start; + auto vc = new VC; + vc.msg = messages; + foreach (m; modules) + m.verify(vc); + messages.checkErrors; + auto ast_verify = watch2.stop; + + foreach (m; modules) + foreach (decl; m.decls) + decl.simplify(); + + timings ~= Measurement("Total", total.stop); + postSema(modules, src_mgr); + + if (options.flag("time")) + foreach (m; timings) + Stderr.formatln("{,-45} {}ms", m.label, m.time*1e3); + */ +} + diff -r f4149d4f6896 -r 9e9f3e7e342b docs/candydoc/modules.ddoc --- a/docs/candydoc/modules.ddoc Tue Aug 12 19:09:01 2008 +0200 +++ b/docs/candydoc/modules.ddoc Tue Aug 12 20:07:35 2008 +0200 @@ -1,1 +1,14 @@ MODULES = + $(MODULE_FULL parser.Action) + $(MODULE_FULL parser.Parser) + $(MODULE_FULL lexer.Keyword) + $(MODULE_FULL lexer.Lexer) + $(MODULE_FULL lexer.Token) + $(MODULE_FULL basic.SmallArray) + $(MODULE_FULL basic.conv) + $(MODULE_FULL basic.Message) + $(MODULE_FULL basic.SourceLocation) + $(MODULE_FULL basic.LiteralParsing) + $(MODULE_FULL basic.Messages) + $(MODULE_FULL basic.Attribute) + $(MODULE_FULL basic.SourceManager) diff -r f4149d4f6896 -r 9e9f3e7e342b dsss.conf --- a/dsss.conf Tue Aug 12 19:09:01 2008 +0200 +++ b/dsss.conf Tue Aug 12 20:07:35 2008 +0200 @@ -1,4 +1,11 @@ +[src/ast] +Target= ast +buildflags = -version=Tango -I./src + +[dang/compiler.d] +Target = Dang +buildflags = -version=Tango -I./src [src] -buildflags = -version=Tango -candydoc -Dqdocs -I./src +buildflags = -version=Tango -candydoc -Dqdocs -I./src -full diff -r f4149d4f6896 -r 9e9f3e7e342b src/ast/Module.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ast/Module.d Tue Aug 12 20:07:35 2008 +0200 @@ -0,0 +1,22 @@ +module ast.Module; + +import ast.Decl; + +class Module +{ + this(char[] moduleName) + { + this.moduleName = moduleName; + } + + void addDecl(Decl decl) + { + decls ~= decl; + } + +private: + Decl[] decls; + char[] moduleName; + bool outputModule = true; +} + diff -r f4149d4f6896 -r 9e9f3e7e342b src/basic/Message.d --- a/src/basic/Message.d Tue Aug 12 19:09:01 2008 +0200 +++ b/src/basic/Message.d Tue Aug 12 20:07:35 2008 +0200 @@ -7,8 +7,6 @@ import tango.stdc.stdlib; -import llvm.type; - import lexer.Token, lexer.Lexer;