changeset 66:8e84db78ad55

- Added support for variadic arguments in error messages.
author aziz
date Sat, 30 Jun 2007 11:27:01 +0000
parents 6c21ae79fbb3
children 996065105910
files trunk/src/Lexer.d trunk/src/main.d
diffstat 2 files changed, 42 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/Lexer.d	Fri Jun 29 19:14:05 2007 +0000
+++ b/trunk/src/Lexer.d	Sat Jun 30 11:27:01 2007 +0000
@@ -11,6 +11,8 @@
 import std.utf;
 import std.uni;
 import std.c.stdlib;
+import std.c.stdarg;
+import std.string;
 
 const char[3] LS = \u2028;
 const char[3] PS = \u2029;
@@ -32,12 +34,49 @@
   MID id;
   Type type;
   uint loc;
+  TypeInfo[] tinfos;
+  void* argptr;
+
   this(Type type, MID id, uint loc)
   {
     this.id = id;
     this.type = type;
     this.loc = loc;
   }
+
+  this(Type type, MID id, uint loc, TypeInfo[] ti, void* argptr)
+  {
+    this(type, id, loc);
+    this.tinfos = ti;
+    this.argptr = argptr;
+  }
+
+  string getMsg()
+  {
+    char[] msg = messages[id];
+
+    if (tinfos.length == 0)
+      return msg;
+
+    foreach (i, arg; arguments)
+      msg = replace(msg, format("{%s}", i), arg);
+  }
+
+  private char[][] arguments()
+  {
+    char[][] args;
+    void* argptr = this.argptr;
+    foreach (ti; tinfos)
+    {
+      if (ti == typeid(char[]))
+        args ~= format(va_arg!(char[])(argptr));
+      else if (ti == typeid(int))
+        args ~= format(va_arg!(int)(argptr));
+      else
+        assert(0, "argument type not supported yet.");
+    }
+    return args;
+  }
 }
 
 class Lexer
@@ -1432,9 +1471,9 @@
       idtable[k.str] = k;
   }
 
-  void error(MID id)
+  void error(MID id, ...)
   {
-    errors ~= new Problem(Problem.Type.Lexer, id, loc);
+    errors ~= new Problem(Problem.Type.Lexer, id, loc, _arguments, _argptr);
   }
 
   public TOK nextToken()
--- a/trunk/src/main.d	Fri Jun 29 19:14:05 2007 +0000
+++ b/trunk/src/main.d	Sat Jun 30 11:27:01 2007 +0000
@@ -37,7 +37,7 @@
 <compilerinfo>`\n);
   foreach (error; lx.errors)
   {
-    writefln(`<error t="%s">%s(%d): %s</error>`, "l", lx.fileName, error.loc, messages[error.id]);
+    writefln(`<error t="%s">%s(%d): %s</error>`, "l", lx.fileName, error.loc, error.getMsg);
   }
   writef(`</compilerinfo>
 <sourcetext>`);