public AstGetSetNewDecl([NotNull] ISourcePosition position, [NotNull] string id, [CanBeNull] AstGetSet expression) : base(position) { if (id == null) throw new ArgumentNullException("id"); _expression = expression; _id = id; _arguments = _expression == null ? new ArgumentsProxy(new List<AstExpr>()) : null; }
/// <summary> /// Creates a new macro context in the specified macro session. /// </summary> /// <param name = "session">The macro expansion session.</param> /// <param name = "invocation">The node that is being expanded.</param> /// <param name = "isJustEffect">Whether the nodes return value will be discarded by the surrounding program.</param> internal MacroContext(MacroSession session, AstGetSet invocation, bool isJustEffect) { if (session == null) throw new ArgumentNullException("session"); if (invocation == null) throw new ArgumentNullException("invocation"); _isJustEffect = isJustEffect; _invocation = invocation; _session = session; _block = new AstScopedBlock(invocation.Position, session.CurrentBlock); _isPartialApplication = _invocation.Arguments.Any(AstPartiallyApplicable.IsPlaceholder); _sentinelBlock = session.Target.CurrentBlock; }
public AstStringConcatenation(ISourcePosition position, AstGetSet simpleConcatPrototype, AstGetSet multiConcatPrototype, params AstExpr[] arguments) : base(position) { if (simpleConcatPrototype == null) throw new ArgumentNullException("simpleConcatPrototype"); if (multiConcatPrototype == null) throw new ArgumentNullException("multiConcatPrototype"); if (arguments == null) arguments = new AstExpr[] {}; _arguments.AddRange(arguments); _simpleConcatPrototype = simpleConcatPrototype; _multiConcatPrototype = multiConcatPrototype; }
private static void _reportMacroNodeNotMacro(CompilerTarget target, string implName, AstGetSet invocation) { target.Loader.ReportMessage( Message.Create(MessageSeverity.Error, String.Format( Resources.MacroSession_NotAMacro, implName), invocation.Position, MessageClasses.NotAMacro)); }
private IMacroExpander _getExpander(AstGetSet macroNode, CompilerTarget target) { IMacroExpander expander = null; AstExpand expansion; EntityRef.MacroCommand mcmd; EntityRef.Function func; if ((expansion = macroNode as AstExpand) != null) { if (expansion.Entity.TryGetMacroCommand(out mcmd)) expander = new MacroCommandExpander(); else if (expansion.Entity.TryGetFunction(out func)) expander = new MacroFunctionExpander(); else _reportMacroNodeNotMacro(target, expansion.Entity.GetType().Name, macroNode); } else { _reportMacroNodeNotMacro(target, macroNode.GetType().Name, macroNode); } return expander; }
public static AstGetSet CreateNeutralExpression(AstGetSet invocation) { var nullLiteral = new AstNull(invocation.File, invocation.Line, invocation.Column); var call = new AstIndirectCall(invocation.File, invocation.Line, invocation.Column, invocation.Call, nullLiteral); if (invocation.Call == PCall.Set) call.Arguments.Add(new AstNull(invocation.File, invocation.Line, invocation.Column)); return call; }
public AstNode ExpandMacro(AstGetSet invocation, bool justEffect) { var target = Target; var context = new MacroContext(this, invocation, justEffect); //Delegate actual expansion to approriate expander var expander = _getExpander(invocation, target); if (expander != null) { expander.Initialize(target, invocation, justEffect); //Macro invocations need to be unique within a session if (_invocations.Contains(invocation)) { target.Loader.ReportMessage( Message.Create(MessageSeverity.Error, String.Format( Resources.MacroSession_MacroNotReentrant, expander.HumanId), invocation.Position, MessageClasses.MacroNotReentrant)); return CreateNeutralExpression(invocation); } _invocations.Add(invocation); //check if this macro is a partial application (illegal) if (invocation.Arguments.Any(AstPartiallyApplicable.IsPlaceholder)) { //Attempt to expand partial macro try { if (!expander.TryExpandPartially(target, context)) { target.Loader.ReportMessage( Message.Create( MessageSeverity.Error, string.Format( Resources.MacroSession_MacroCannotBeAppliedPartially, expander.HumanId), invocation.Position, MessageClasses.PartialApplicationNotSupported)); return CreateNeutralExpression(invocation); } } catch (Exception e) { _setupDefaultExpression(context); _reportException(context, expander, e); } } else { //Actual macro expansion takes place here try { var cub = target.CurrentBlock; expander.Expand(target, context); if(!ReferenceEquals(cub,target.CurrentBlock)) throw new PrexoniteException("Macro must restore previous lexical scope."); } catch (Exception e) { _setupDefaultExpression(context); _reportException(context, expander, e); } } } //Sanitize output var ast = context.Block; //ensure that there is at least null being pushed onto the stack)) if (!justEffect && ast.Expression == null && !context.SuppressDefaultExpression) ast.Expression = CreateNeutralExpression(invocation); var node = AstNode._GetOptimizedNode(Target, ast); return node; }
public override void Initialize(CompilerTarget target, AstGetSet macroNode, bool justEffect) { var expansion = (AstExpand)macroNode; MacroFunction = null; EntityRef.Function functionRef; if (!expansion.Entity.TryGetFunction(out functionRef)) throw new InvalidOperationException(string.Format(Resources.MacroFunctionExpander_ExpectedFunctionReference, expansion.Entity)); PValue value; PFunction func; if (functionRef.TryGetEntity(target.Loader, out value) && (func = value.Value as PFunction) != null) { HumanId = functionRef.Id; MacroFunction = func; } else { target.Loader.ReportMessage( Message.Create( MessageSeverity.Error, String.Format( Resources.MacroFunctionExpander_MacroFunctionNotAvailable, functionRef, target.Function.Id, target.Loader.ParentApplication.Module.Name), macroNode.Position, MessageClasses.NoSuchMacroFunction)); HumanId = "could_not_resolve_macro_function"; } }
public abstract void Initialize(CompilerTarget target, AstGetSet macroNode, bool justEffect);
public override void Initialize(CompilerTarget target, AstGetSet macroNode, bool justEffect) { var expansion = (AstExpand) macroNode; MacroCommand = null; EntityRef.MacroCommand mcmdRef; if(!expansion.Entity.TryGetMacroCommand(out mcmdRef)) throw new InvalidOperationException(string.Format(Resources.MacroCommandExpander_MacroCommandExpected, expansion.Entity)); PValue value; MacroCommand mcmd; if (mcmdRef.TryGetEntity(target.Loader, out value) && (mcmd = value.Value as MacroCommand) != null) { HumanId = mcmdRef.Id; MacroCommand = mcmd; } else { target.Loader.ReportMessage(Message.Create(MessageSeverity.Error, String.Format( Resources.MacroCommandExpander_CannotFindMacro, mcmdRef.Id), macroNode.Position, MessageClasses.NoSuchMacroCommand)); HumanId = "cannot_find_macro_command"; } }
/// <summary> /// Copies the base class fields from this to the target. /// </summary> /// <param name = "target">The object that shall reveice the values from this object.</param> protected virtual void CopyBaseMembers(AstGetSet target) { target.Arguments.AddRange(Arguments); }