Mercurial > projects > dil
changeset 758:f4b9680c0e16
Revised module dil.SettingsLoader.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Thu, 14 Feb 2008 03:31:19 +0100 |
parents | e4b60543c5e8 |
children | 9c47f377ca0b |
files | trunk/src/config.d trunk/src/dil/SettingsLoader.d trunk/src/dil/semantic/Module.d trunk/src/dil/semantic/Pass1.d trunk/src/dil/semantic/Symbol.d trunk/src/dil/semantic/Symbols.d trunk/src/main.d |
diffstat | 7 files changed, 152 insertions(+), 132 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/src/config.d Wed Feb 13 22:08:58 2008 +0100 +++ b/trunk/src/config.d Thu Feb 14 03:31:19 2008 +0100 @@ -1,18 +1,25 @@ -// Relative paths are resolved from the directory of dil's executable. +/// The configuration file of dil. +/// +/// Relative paths are resolved from the directory of the executable. +module config; -// Path to the language file. +/// Path to the language file. var langfile = "lang_en.d"; -// An array of import paths to look for modules. -var import_paths = []; // E.g.: ["src/", "import/"] -// DDoc macro file paths. -var ddoc_files = []; // E.g.: ["src/mymacros.ddoc", "othermacros.ddoc"] -/* - Customizing error messages. - 0: file path to the source text. - 1: line number. - 2: column number. - 3: error message. -*/ + +/// An array of import paths to look for modules. +var import_paths = []; /// E.g.: ["src/", "import/"] + +/// DDoc macro file paths. +var ddoc_files = []; /// E.g.: ["src/mymacros.ddoc", "othermacros.ddoc"] + +/// Customizable formats for error messages. +/// +/// <ul> +/// <li>0: file path to the source text.</li> +/// <li>1: line number.</li> +/// <li>2: column number.</li> +/// <li>3: error message.</li> +/// </ul> var lexer_error = "{0}({1},{2})L: {3}"; -var parser_error = "{0}({1},{2})P: {3}"; -var semantic_error = "{0}({1},{2})S: {3}"; +var parser_error = "{0}({1},{2})P: {3}"; /// ditto +var semantic_error = "{0}({1},{2})S: {3}"; /// ditto
--- a/trunk/src/dil/SettingsLoader.d Wed Feb 13 22:08:58 2008 +0100 +++ b/trunk/src/dil/SettingsLoader.d Thu Feb 14 03:31:19 2008 +0100 @@ -8,125 +8,120 @@ import dil.Messages; import dil.ast.Node, dil.ast.Declarations, dil.ast.Expressions; import dil.semantic.Module; -import dil.File; -import tango.io.FilePath; +import dil.semantic.Pass1; +import dil.semantic.Symbol; +import dil.semantic.Symbols; +import dil.Information; import common; -void loadSettings() -{ - scope execPath = new FilePath(GetExecutableFilePath()); - execPath = new FilePath(execPath.folder()); +import tango.io.FilePath; - // Load config.d - auto filePath = resolvePath(execPath, "config.d"); - auto modul = new Module(filePath); - modul.parse(); +struct SettingsLoader +{ + InfoManager infoMan; + Module mod; /// Current module. - if (modul.hasErrors) - throw new Exception("There are errors in " ~ filePath ~ "."); - - foreach (decl; modul.root.children) + static SettingsLoader opCall(InfoManager infoMan) { - auto v = decl.Is!(VariablesDeclaration); - if (v is null) - continue; + SettingsLoader sl; + sl.infoMan = infoMan; + return sl; + } - auto variableName = v.names[0].str; - auto e = v.inits[0]; - if (!e) - throw new Exception(variableName ~ " variable has no value set."); + void error(Token* token, char[] formatMsg, ...) + { + auto location = token.getErrorLocation(); + auto msg = Format(_arguments, _argptr, formatMsg); + infoMan ~= new SemanticError(location, msg); + } - switch (variableName) - { - case "langfile": - if (auto val = e.Is!(StringExpression)) - GlobalSettings.langFile = val.getString(); - break; - case "import_paths": - if (auto array = e.Is!(ArrayInitExpression)) - { - foreach (value; array.values) - if (auto str = value.Is!(StringExpression)) - GlobalSettings.importPaths ~= str.getString(); - } - else - throw new Exception("import_paths variable is set to "~e.classinfo.name~" instead of an ArrayInitializer."); - break; - case "ddoc_files": - if (auto array = e.Is!(ArrayInitExpression)) - { - foreach (value; array.values) - if (auto str = value.Is!(StringExpression)) - GlobalSettings.ddocFilePaths ~= resolvePath(execPath, str.getString()); - } - else - throw new Exception("import_paths variable is set to "~e.classinfo.name~" instead of an ArrayInitializer."); - break; - case "lexer_error": - if (auto val = e.Is!(StringExpression)) - GlobalSettings.lexerErrorFormat = val.getString(); - break; - case "parser_error": - if (auto val = e.Is!(StringExpression)) - GlobalSettings.parserErrorFormat = val.getString(); - break; - case "semantic_error": - if (auto val = e.Is!(StringExpression)) - GlobalSettings.semanticErrorFormat = val.getString(); - break; - default: - } + T getValue(T)(char[] name) + { + auto var = mod.lookup(name); + if (!var) // Returning T.init instead of null, because dmd gives an error. + return error(mod.firstToken, "variable '{}' is not defined", name), T.init; + auto t = var.node.begin; + if (!var.isVariable) + return error(t, "'{}' is not a variable declaration", name), T.init; + auto value = var.to!(Variable).value; + if (!value) + return error(t, "'{}' variable has no value set", name), T.init; + T val = value.Is!(T); // Try casting to T. + if (!val) + error(value.begin, "the value of '{}' is not of type {}", name, typeof(T).stringof); + return val; + } + + T castTo(T)(Node n) + { + char[] type; + is(T == StringExpression) && (type = "char[]"); + if (!n.Is!(T)) + error(n.begin, "expression is not of type {}", type); + return n.Is!(T); } - // Load language file. - filePath = resolvePath(execPath, GlobalSettings.langFile); - modul = new Module(filePath); - modul.parse(); - - if (modul.hasErrors) - throw new Exception("There are errors in "~filePath~"."); - - char[][] messages; - foreach (decl; modul.root.children) + void load() { - auto v = decl.Is!(VariablesDeclaration); - if (v is null) - continue; + scope execPath = new FilePath(GetExecutableFilePath()); + execPath = new FilePath(execPath.folder()); + + // Load config.d + auto filePath = resolvePath(execPath, "config.d"); + mod = new Module(filePath, infoMan); + mod.parse(); + + if (mod.hasErrors) + return; + + auto pass1 = new SemanticPass1(mod); + pass1.start(); + + if (auto val = getValue!(StringExpression)("langfile")) + GlobalSettings.langFile = val.getString(); - auto variableName = v.names[0].str; - auto e = v.inits[0]; - if (!e) - throw new Exception(variableName~" variable in "~filePath~" has no value set."); + if (auto array = getValue!(ArrayInitExpression)("import_paths")) + foreach (value; array.values) + if (auto str = castTo!(StringExpression)(value)) + GlobalSettings.importPaths ~= str.getString(); + if (auto array = getValue!(ArrayInitExpression)("ddoc_files")) + foreach (value; array.values) + if (auto str = castTo!(StringExpression)(value)) + GlobalSettings.ddocFilePaths ~= resolvePath(execPath, str.getString()); + if (auto val = getValue!(StringExpression)("lexer_error")) + GlobalSettings.lexerErrorFormat = val.getString(); + if (auto val = getValue!(StringExpression)("parser_error")) + GlobalSettings.parserErrorFormat = val.getString(); + if (auto val = getValue!(StringExpression)("semantic_error")) + GlobalSettings.semanticErrorFormat = val.getString(); - switch (variableName) + // Load language file. + filePath = resolvePath(execPath, GlobalSettings.langFile); + mod = new Module(filePath); + mod.parse(); + + if (mod.hasErrors) + return; + + pass1 = new SemanticPass1(mod); + pass1.start(); + + if (auto array = getValue!(ArrayInitExpression)("messages")) { - case "messages": - if (auto array = e.Is!(ArrayInitExpression)) - { - foreach (value; array.values) - { - if (auto str = value.Is!(StringExpression)) - messages ~= str.getString(); - } - } - else - throw new Exception("messages variable is set to "~e.classinfo.name~" instead of an ArrayInitializer."); - break; - case "lang_code": - if (auto str = e.Is!(StringExpression)) - GlobalSettings.langCode = str.getString(); - break; - default: + char[][] messages; + foreach (value; array.values) + if (auto str = castTo!(StringExpression)(value)) + messages ~= str.getString(); + if (messages.length != MID.max+1) + error(mod.firstToken, + "messages table in {} must exactly have {} entries, but not {}.", + filePath, MID.max+1, messages.length); + GlobalSettings.messages = messages; + dil.Messages.SetMessages(messages); } + if (auto val = getValue!(StringExpression)("lang_code")) + GlobalSettings.langCode = val.getString(); } - if (messages.length != MID.max+1) - throw new Exception( - Format( - "messages table in {0} must exactly have {1} entries, but {2} were found.", - filePath, MID.max+1, messages.length) - ); - GlobalSettings.messages = messages; - dil.Messages.SetMessages(messages); } string resolvePath(FilePath execPath, string filePath) @@ -139,9 +134,7 @@ version(Windows) { private extern(Windows) uint GetModuleFileNameA(void*, char*, uint); -/++ - Get the fully qualified path to this executable. -+/ +/// Get the fully qualified path to this executable. char[] GetExecutableFilePath() { alias GetModuleFileNameA GetModuleFileName; @@ -171,9 +164,7 @@ else version(linux) { private extern(C) size_t readlink(char* path, char* buf, size_t bufsize); -/++ - Get the fully qualified path to this executable. -+/ +/// Get the fully qualified path to this executable. char[] GetExecutableFilePath() { char[] buffer = new char[256];
--- a/trunk/src/dil/semantic/Module.d Wed Feb 13 22:08:58 2008 +0100 +++ b/trunk/src/dil/semantic/Module.d Thu Feb 14 03:31:19 2008 +0100 @@ -88,6 +88,11 @@ } } + Token* firstToken() + { + return parser.lexer.firstToken(); + } + /// Returns true if there are errors in the source file. bool hasErrors() {
--- a/trunk/src/dil/semantic/Pass1.d Wed Feb 13 22:08:58 2008 +0100 +++ b/trunk/src/dil/semantic/Pass1.d Thu Feb 14 03:31:19 2008 +0100 @@ -324,9 +324,10 @@ return error(vd.begin, MSG.InterfaceCantHaveVariables), vd; // Insert variable symbols in this declaration into the symbol table. - foreach (name; vd.names) + foreach (i, name; vd.names) { auto variable = new Variable(name, protection, storageClass, linkageType, vd); + variable.value = vd.inits[i]; vd.variables ~= variable; insert(variable, name); }
--- a/trunk/src/dil/semantic/Symbol.d Wed Feb 13 22:08:58 2008 +0100 +++ b/trunk/src/dil/semantic/Symbol.d Thu Feb 14 03:31:19 2008 +0100 @@ -84,6 +84,12 @@ mixin(isX!("OverloadSet")); // mixin(isX!("Type")); + Class to(Class)() + { + assert(mixin(`this.sid == mixin("SYM." ~ typeof(Class).stringof)`)); + return cast(Class)cast(void*)this; + } + /// Returns: the fully qualified name of this symbol. /// E.g.: dil.semantic.Symbol.Symbol.getFQN char[] getFQN()
--- a/trunk/src/dil/semantic/Symbols.d Wed Feb 13 22:08:58 2008 +0100 +++ b/trunk/src/dil/semantic/Symbols.d Thu Feb 14 03:31:19 2008 +0100 @@ -9,7 +9,7 @@ import dil.semantic.SymbolTable; import dil.semantic.Types; import dil.ast.Node; -import dil.lexer.Identifier; +import dil.lexer.IdTable; import dil.Enums; import common; @@ -30,6 +30,13 @@ return symbolTable.lookup(name); } + /// Look up name in the table. + Symbol lookup(string name) + { + auto id = IdTable.lookup(name); + return id ? symbolTable.lookup(id) : null; + } + /// Insert a symbol into the table. void insert(Symbol s, Identifier* name) {
--- a/trunk/src/main.d Wed Feb 13 22:08:58 2008 +0100 +++ b/trunk/src/main.d Thu Feb 14 03:31:19 2008 +0100 @@ -41,7 +41,10 @@ void main(char[][] args) { - dil.SettingsLoader.loadSettings(); + auto infoMan = new InfoManager(); + SettingsLoader(infoMan).load(); + if (infoMan.info.length) + return printErrors(infoMan); if (args.length <= 1) return Stdout(helpMain()).newline; @@ -53,7 +56,7 @@ if (args.length < 2) return printHelp("compile"); - auto infoMan = new InfoManager(); + infoMan = new InfoManager(); auto filePaths = args[2..$]; foreach (filePath; filePaths) { @@ -108,7 +111,7 @@ filePaths ~= arg; } - auto infoMan = new InfoManager(); + infoMan = new InfoManager(); // Execute command. cmd.DDoc.execute(filePaths, destination, macroPaths, incUndoc, verbose, infoMan); if (infoMan.info.length) @@ -220,7 +223,7 @@ if (!sourceText) sourceText = new SourceText(filePath, true); - auto infoMan = new InfoManager(); + infoMan = new InfoManager(); auto lx = new Lexer(sourceText, infoMan); lx.scanAll(); auto token = lx.firstToken(); @@ -243,7 +246,7 @@ if (args[2] != "German") return Stdout.formatln("Error: unrecognized target language \"{}\"", args[2]); - auto infoMan = new InfoManager(); + infoMan = new InfoManager(); auto filePath = args[3]; auto mod = new Module(filePath, infoMan); // Parse the file.