Enhanced C#
Language of your choice: library documentation

Documentation moved to ecsharp.net

GitHub doesn't support HTTP redirects, so you'll be redirected in 3 seconds.

 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events Pages
Public fields | Properties | Public Member Functions | List of all members
LeMP.MacroProcessor Class Reference

Encapsulates the LeMP engine, a simple LISP-style macro processor, suitable for running LLLPG and other lexical macros. More...


Source file:

Remarks

Encapsulates the LeMP engine, a simple LISP-style macro processor, suitable for running LLLPG and other lexical macros.

MacroProcessor itself only cares about a few nodes including #importMacros and #unimportMacros, and { braces } (for scoping the #import statements). The macro processor should be configured with any needed macros like this:

var prelude = typeof(LeMP.Prelude.BuiltinMacros); // the default prelude
var MP = new MacroProcessor(prelude, sink);
MP.AddMacros(typeof(LeMP.StandardMacros).Assembly);
MP.PreOpenedNamespaces.Add((Symbol) "LeMP.Prelude"); // already done for you
MP.PreOpenedNamespaces.Add((Symbol) "LeMP");

In order for the input code to have access to macros, two steps are necessary: you have to add the macro classes with AddMacros and then you have to import the namespace that contains the class(es). Higher-level code (e.g. Compiler) can define "always-open" namespaces by adding entries to PreOpenedNamespaces, and the code being processed can open additional namespaces with a #importMacros(Namespace) statement (in LES, "import_macros Namespace" can be used as a synonym if PreOpenedNamespaces contains LeMP.Prelude).

MacroProcessor is not aware of any distinction between "statements" and "expressions"; it will run macros no matter where they are located, whether as standalone statements, attributes, or arguments to functions.

MacroProcessor's main responsibilities are to keep track of a table of registered macros (call AddMacros to register more), to keep track of which namespaces are open (namespaces can be imported by #import, or by import which is defined in the LES prelude); to scan the input for macros to call; and to control the printout of messages.

This class processes a batch of files at once. Call either ProcessSynchronously or ProcessParallel. Parallelizing on a file-by-file basis is easy; each source file is completely independent, since no semantic analysis is being done.

TODO: add method for processing an LNode instead of a list of source files.

Public fields

int MaxExpansions = 255
 
MMap< object, object > DefaultScopedProperties = new MMap<object, object>()
 Default values of scoped properties. This map is empty by default. More...
 

Properties

IMessageSink Sink [get, set]
 
static MacroProcessor Current [get]
 Returns the MacroProcessor running on the current thread, or null if none. More...
 
ICollection< SymbolPreOpenedNamespaces [get]
 Macros in these namespaces will be available without an explicit import command (#importMacros). By default this list has one item: @LeMP.Prelude (i.e. (Symbol)"LeMP.Prelude") More...
 
TimeSpan AbortTimeout [get, set]
 

Public Member Functions

 MacroProcessor (Type prelude, IMessageSink sink)
 
bool AddMacros (Type type)
 
bool AddMacros (Assembly assembly, bool writeToSink=true)
 
VList< LNodeProcessSynchronously (VList< LNode > stmts)
 Processes a list of nodes directly on the current thread. More...
 
void ProcessSynchronously (IReadOnlyList< InputOutput > sourceFiles, Action< InputOutput > onProcessed=null)
 Processes source files one at a time (may be easier for debugging). More...
 
void ProcessParallel (IReadOnlyList< InputOutput > sourceFiles, Action< InputOutput > onProcessed=null)
 Processes source files in parallel. All files are fully processed before the method returns. More...
 
Task< VList< LNode > >[] ProcessAsync (IReadOnlyList< InputOutput > sourceFiles, Action< InputOutput > onProcessed=null)
 Processes source files in parallel using .NET Tasks. The method returns immediately. More...
 

Member Function Documentation

Task<VList<LNode> > [] LeMP.MacroProcessor.ProcessAsync ( IReadOnlyList< InputOutput sourceFiles,
Action< InputOutput onProcessed = null 
)
inline

Processes source files in parallel using .NET Tasks. The method returns immediately.

Referenced by LeMP.MacroProcessor.ProcessParallel().

void LeMP.MacroProcessor.ProcessParallel ( IReadOnlyList< InputOutput sourceFiles,
Action< InputOutput onProcessed = null 
)
inline

Processes source files in parallel. All files are fully processed before the method returns.

References LeMP.MacroProcessor.ProcessAsync().

VList<LNode> LeMP.MacroProcessor.ProcessSynchronously ( VList< LNode stmts)
inline

Processes a list of nodes directly on the current thread.

Note: AbortTimeout doesn't work when using this overload.

void LeMP.MacroProcessor.ProcessSynchronously ( IReadOnlyList< InputOutput sourceFiles,
Action< InputOutput onProcessed = null 
)
inline

Processes source files one at a time (may be easier for debugging).

Member Data Documentation

MMap<object, object> LeMP.MacroProcessor.DefaultScopedProperties = new MMap<object, object>()

Default values of scoped properties. This map is empty by default.

The @#inputFolder and @#inputFileName properties (note: @ is EC# syntax for Symbol) are not normally stored in this collection; when you use ProcessSynchronously or ProcessParallel, @#inputFolder and @#inputFileName are set according to the folder and filename in InputOutput.FileName. However, @#inputFolder is not set if the filename has no folder component, so this collection could be used to override @#inputFolder in that case.

Property Documentation

MacroProcessor LeMP.MacroProcessor.Current
staticget

Returns the MacroProcessor running on the current thread, or null if none.

ICollection<Symbol> LeMP.MacroProcessor.PreOpenedNamespaces
get

Macros in these namespaces will be available without an explicit import command (#importMacros). By default this list has one item: @LeMP.Prelude (i.e. (Symbol)"LeMP.Prelude")