Artifact Content
Not logged in

Artifact 442c0afd591f3c6aa12c9e1f6777562cd5fd25d4


     1  /**
     2   * Authors: k.inaba
     3   * License: NYSL 0.9982 http://www.kmonos.net/nysl/
     4   *
     5   * Error Information for Polemy Programming Language
     6   */
     7  module polemy.failure;
     8  import polemy._common;
     9  
    10  /// Represents a position in source codes
    11  
    12  alias immutable(LexPosition_t) LexPosition;
    13  
    14  /// Represents a position in source codes
    15  
    16  class LexPosition_t
    17  {
    18  	immutable string filename; /// name of the source file
    19  	immutable int    lineno;   /// 1-origin
    20  	immutable int    column;   /// 1-origin
    21  
    22  	mixin SimpleClass;
    23  	override string toString() const
    24  		{ return sprintf!("%s:%d:%d")(filename, lineno, column); }
    25  	static LexPosition dummy;
    26  	static this(){ dummy = new LexPosition("<nowhere>",0,0); }
    27  }
    28  
    29  unittest
    30  {
    31  	auto p = new LexPosition("hello.cpp", 123, 45);
    32  
    33  	assert_eq( p.filename, "hello.cpp" );
    34  	assert_eq( p.lineno, 123 );
    35  	assert_eq( p.column, 45 );
    36  	assert_eq( text(p), "hello.cpp:123:45" );
    37  
    38  	assert( !__traits(compiles, new LexPosition) );
    39  	assert( !__traits(compiles, p.filename="foo") );
    40  	assert( !__traits(compiles, p.lineno  =789) );
    41  	assert( !__traits(compiles, p.column  =222) );
    42  
    43  	auto q = new LexPosition("hello.cpp", 123, 46);
    44  	assert_lt( p, q );
    45  	assert_ne( p, q );
    46  }
    47  
    48  /*mixin*/
    49  template ExceptionWithPosition()
    50  {
    51  	LexPosition pos;
    52  	this( LexPosition pos, string msg, string file=null, size_t line=0, Throwable next=null )
    53  	{
    54  		string fullmsg = pos is null ? sprintf!("\n[??] %s")(msg)
    55  		                             : sprintf!("\n[%s] %s")(pos, msg);
    56  		foreach_reverse(i,_; callstack_pos)
    57  		{
    58  			LexPosition p = callstack_pos[i];
    59  			string      m = callstack_msg[i];
    60  			fullmsg ~= p is null ? sprintf!("\n[??] %s")(m)
    61  		                         : sprintf!("\n[%s] %s")(p, m);
    62  		}
    63  		super(fullmsg, file, line, next);
    64  		this.pos = pos;
    65  	}
    66  	this( string msg, string file=null, size_t line=0, Throwable next=null )
    67  	{
    68  		this(null, msg, file, line, next);
    69  	}
    70  }
    71  
    72  class UnexpectedEOF    : Exception { mixin ExceptionWithPosition; } /// EOF during lexing/parsing
    73  class LexException     : Exception { mixin ExceptionWithPosition; } /// Lexer errors
    74  class ParseException   : Exception { mixin ExceptionWithPosition; } /// Parser errors
    75  class RuntimeException : Exception { mixin ExceptionWithPosition; } /// Evaluator errors
    76  
    77  /// Per-thread call stack management.
    78  /// This scoped class's ctor&dtor maintain the callstack.
    79  /// TODO: make it "per-evaluator" !!!!!!!!!!!
    80  
    81  scope class PushCallStack
    82  {
    83  	this(LexPosition pos, string msg) { callstackEnterFunction(pos,msg); }
    84  	~this() { callstackLeaveFunction(); }
    85  }
    86  
    87  LexPosition[] callstack_pos;
    88  string[]      callstack_msg;
    89  
    90  private void callstackEnterFunction(LexPosition pos, string msg)
    91  {
    92  	callstack_pos ~= pos;
    93  	callstack_msg ~= msg;
    94  }
    95  
    96  private void callstackLeaveFunction()
    97  {
    98  	callstack_pos.length -= 1;
    99  	callstack_msg.length -= 1;
   100  }