[svn] r5878: nemerle/trunk/ncc: parsing/Lexer.n parsing/PreParser.n
passes.n testsuite/positive/pragma-ind...
malekith
svnadmin at nemerle.org
Fri Nov 4 11:31:57 CET 2005
Log:
Move LexerFileIndent implementation into LexerBase (it should also work for LexerString, which is used for completion). Implement PreParser-switching when #pragma indent is seen.
Author: malekith
Date: Fri Nov 4 11:31:56 2005
New Revision: 5878
Added:
nemerle/trunk/ncc/testsuite/positive/pragma-indent.n
Modified:
nemerle/trunk/ncc/parsing/Lexer.n
nemerle/trunk/ncc/parsing/PreParser.n
nemerle/trunk/ncc/passes.n
Modified: nemerle/trunk/ncc/parsing/Lexer.n
==============================================================================
--- nemerle/trunk/ncc/parsing/Lexer.n (original)
+++ nemerle/trunk/ncc/parsing/Lexer.n Fri Nov 4 11:31:56 2005
@@ -31,6 +31,7 @@
using System;
using Nemerle.Collections;
+using Nemerle.Utility;
namespace Nemerle.Compiler {
@@ -236,6 +237,68 @@
protected id_buffer : StringBuilder = StringBuilder ();
+ #region Indentation syntax
+ // Variables for indentation-based syntax
+ // The location where a token should be automatically inserted
+ protected mutable insert_location : Location;
+ // Used by GetToken() to store that token that it postpones when insert_indent = true
+ protected mutable tok_pending : Token;
+ // Whether we are currently adding whitespaces to indentString
+ protected mutable counting_indentation : bool;
+ // Whether GetToken() should return a Token.Indent
+ protected mutable insert_indent : bool;
+ // String holding the current line's indent
+ protected mutable indent_string : string;
+
+ [Accessor]
+ protected mutable in_indentation_mode : bool;
+
+ public SwitchToIndentationMode () : void
+ {
+ in_indentation_mode = true;
+ counting_indentation = true;
+ indent_string = "";
+ }
+
+ pragma_indent () : void
+ {
+ unless (in_indentation_mode) {
+ SwitchToIndentationMode ();
+ _ = read_to_the_end_of_line ();
+ throw PragmaIndent ()
+ }
+ }
+
+ do_read () : char
+ {
+ def ch = read_from_input ();
+ // Message.Debug (Location, $"ch = '$ch'");
+
+ when (in_indentation_mode) {
+ // Start counting indentation anew after a newline
+ if (ch == '\n' || ch == '\r') {
+ // Message.Debug (Location, $"start");
+ indent_string = "";
+ counting_indentation = true;
+ //Message.Debug (Location (file_idx, line, col), "countingIndentation ON");
+ }
+ else when (counting_indentation) {
+ if (ch == '\t' || ch == ' ')
+ indent_string += ch.ToString();
+ // We have a non-space character, so stop counting indentation
+ // and indicate that we have a new line to process
+ else {
+ // Message.Debug (Location, $"stop");
+ counting_indentation = false;
+ insert_indent = true;
+ }
+ }
+ }
+
+ ch
+ }
+ #endregion
+
#region PREPROCESSOR VARIABLES
/** if there was only white chars from beginnig of line */
@@ -263,6 +326,10 @@
public this (name : string) { this.name = name; }
}
+ public class PragmaIndent : System.Exception
+ {
+ }
+
protected this ()
{
line = 1;
@@ -277,7 +344,7 @@
line_stack = -1;
}
- abstract protected do_read () : char;
+ abstract protected read_from_input () : char;
public abstract Dispose () : void;
@@ -765,6 +832,10 @@
{
mutable eof = false;
+ // Location where possible automatic token insertion will take place
+ when (in_indentation_mode)
+ insert_location = Location;
+
def loop (shift : bool) {
when (shift) ignore (read ());
def ch =
@@ -948,26 +1019,37 @@
}
}
+
public virtual GetToken () : Token
{
+ if (tok_pending != null) {
+ def tok = tok_pending;
+ tok_pending = null;
+ tok
+ } else {
unless (isPendingChar)
_ = eat_whitespace ();
+ if (insert_indent) {
+ insert_indent = false;
+ Token.Indent (insert_location, indent_string)
+ } else {
def last_line = line;
def last_col = col;
def tok = do_get_token ();
tok.Location = Location (file_idx, last_line, last_col, line, col);
tok
}
+ }
+ }
public Location : Location
{
get { Location (file_idx, line, col) }
}
- parse_preprocessor () : void
+ read_to_the_end_of_line () : string
{
- def read_to_the_end_of_line () {
mutable c = ' ';
def line = StringBuilder (80);
while (c != '\n') {
@@ -976,7 +1058,10 @@
catch { _ is LexerBase.Error => c = '\n' }
};
line.ToString ()
- };
+ }
+
+ parse_preprocessor () : void
+ {
// eof isn't checked, because we are eating and expecting something
// not white before end of line
def eat_spaces () : char {
@@ -1128,6 +1213,9 @@
unless (did_something)
WarningOptions.AddPragmaWarning (file_idx, line, 1 * negate)
+ | "indent" =>
+ pragma_indent ();
+
| _ =>
Message.Warning (1633, this.Location, "unrecognized #pragma directive");
_ = read_to_the_end_of_line ();
@@ -1332,7 +1420,7 @@
}
- override protected do_read () : char
+ override protected read_from_input () : char
{
def inp = reader.Read ();
if (inp >= 0)
@@ -1449,7 +1537,7 @@
public override Dispose () : void { }
- override protected do_read () : char
+ override protected read_from_input () : char
{
if (pos < reader.Length) {
def ch = reader[pos];
@@ -1526,84 +1614,6 @@
}
}
-
-public class LexerFileIndent : LexerFile
-{
- // Variables for indentation-based syntax
- // The location where a token should be automatically inserted
- protected mutable insertLocation : Location;
- // Used by GetToken() to store that token that it postpones when insert_indent = true
- protected mutable tokPending : Token;
- // Whether we are currently adding whitespaces to indentString
- protected mutable countingIndentation : bool;
- // Whether GetToken() should return a Token.Indent
- protected mutable insert_indent : bool;
- // String holding the current line's indent
- protected mutable indentString : string;
-
-
- public this (fn : string)
- {
- base (fn);
- countingIndentation = true;
- indentString = "";
- }
-
- override protected do_read () : char
- {
- def ch = base.do_read ();
- // Message.Debug (Location, $"ch = '$ch'");
-
- // Start counting indentation anew after a newline
- if (ch == '\n' || ch == '\r') {
- // Message.Debug (Location, $"start");
- indentString = "";
- countingIndentation = true;
- //Message.Debug (Location (file_idx, line, col), "countingIndentation ON");
- }
- else when (countingIndentation) {
- if (ch == '\t' || ch == ' ')
- indentString += ch.ToString();
- // We have a non-space character, so stop counting indentation
- // and indicate that we have a new line to process
- else {
- // Message.Debug (Location, $"stop");
- countingIndentation = false;
- insert_indent = true;
- }
- }
-
- ch
- }
-
- override protected eat_whitespace () : bool
- {
- // Location where possible automatic token insertion will take place
- insertLocation = Location (file_idx, line, col);
-
- base.eat_whitespace ();
- }
-
- public override GetToken () : Token
- {
- if (tokPending != null) {
- def tok = tokPending;
- tokPending = null;
- tok;
- } else {
- unless (isPendingChar)
- _ = eat_whitespace ();
-
- if (insert_indent) {
- insert_indent = false;
- Token.Indent (insertLocation, indentString)
- } else
- base.GetToken ()
- }
- }
-} // LexerFileIndent
-
-
public enum SyntaxType {
| Identifier
| Keyword
Modified: nemerle/trunk/ncc/parsing/PreParser.n
==============================================================================
--- nemerle/trunk/ncc/parsing/PreParser.n (original)
+++ nemerle/trunk/ncc/parsing/PreParser.n Fri Nov 4 11:31:56 2005
@@ -437,16 +437,36 @@
}
}
+ indention_based_copy () : PreParser
+ {
+ def copy = PreParserIndent (lexer);
+ copy.last_token = last_token;
+ copy.Env = Env;
+ copy.finished = finished;
+ copy
+ }
+
public ParseTopLevel () : Token.BracesGroup {
+ try {
def stream = ParseTopLevelImpl ();
lexer.Dispose (); // make lexer release file handle
Token.BracesGroup (stream)
+ } catch {
+ | _ is LexerBase.PragmaIndent =>
+ indention_based_copy ().ParseTopLevel ()
+ }
}
public PreParse () : Token.BracesGroup {
+ try {
def top = parse_brace_group (Location.Default);
- unless (finished) Message.Error (lexer.Location, "expected end of file, encountered closing brace");
+ unless (finished)
+ Message.Error (lexer.Location, "expected end of file, encountered closing brace");
top
+ } catch {
+ | _ is LexerBase.PragmaIndent =>
+ indention_based_copy ().PreParse ()
+ }
}
}
}
Modified: nemerle/trunk/ncc/passes.n
==============================================================================
--- nemerle/trunk/ncc/passes.n (original)
+++ nemerle/trunk/ncc/passes.n Fri Nov 4 11:31:56 2005
@@ -134,7 +134,11 @@
// if it was not initialized outside the Run
when (LexingPipeline == null)
if (Options.IndentationSyntax)
- LexingPipeline = LexerFileIndent;
+ LexingPipeline = fun (fn) {
+ def l = LexerFile (fn);
+ l.SwitchToIndentationMode ();
+ l
+ }
else
LexingPipeline = LexerFile;
when (OnInit != null) OnInit ();
Added: nemerle/trunk/ncc/testsuite/positive/pragma-indent.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/positive/pragma-indent.n Fri Nov 4 11:31:56 2005
@@ -0,0 +1,7 @@
+#pragma indent
+class C
+ foo = 13
+ bar : string
+ baz : bool
+
+()
More information about the svn
mailing list