Expr HandleForeach() { SourceLocation location = _parser.PrevNonCommentLocation; bool openPar = _parser.Match(TokenizerToken.OpenPar); string name = _parser.ReadIdentifier(); if (name == "let") { name = _parser.ReadIdentifier(); } if (name == null) { return(new SyntaxErrorExpr(_parser.Location, "Expected identifier (variable name).")); } AccessorLetExpr var = new AccessorLetExpr(_parser.PrevNonCommentLocation, name); Expr e = _scope.Declare(var); if (e is SyntaxErrorExpr) { return(e); } if (!_parser.MatchIdentifier("in")) { return(new SyntaxErrorExpr(_parser.Location, "Expected in keyword.")); } Expr generator = Expression(0); if (openPar && !_parser.Match(TokenizerToken.ClosePar)) { return(new SyntaxErrorExpr(_parser.Location, "Expected closing parenthesis.")); } Expr code = HandleStatement(); return(new ForeachExpr(location, var, generator, code)); }
public ForeachExpr(SourceLocation location, AccessorLetExpr var, Expr generator, Expr code) : base(location, true, false) { Variable = var; Generator = generator; Code = code; }
Expr HandleFunction() { var funcLocation = _parser.PrevNonCommentLocation; string name = _parser.ReadIdentifier(); AccessorLetExpr funcName = null; if (name != null) { funcName = new AccessorLetExpr(_parser.PrevNonCommentLocation, name); Expr eRegName = _scope.Declare(name, funcName); if (eRegName is SyntaxErrorExpr) { return(eRegName); } } IReadOnlyList <AccessorLetExpr> parameters, closures; Expr body = HandleFuncParametersAndBody(out parameters, out closures, false); var f = new FunctionExpr(funcLocation, parameters, body, closures, funcName); if (funcName == null) { return(f); } return(new AssignExpr(funcLocation, funcName, f)); }
internal void AddClosure(AccessorLetExpr a) { if (_closures == null) { _closures = new HashSet <AccessorLetExpr>(); } _closures.Add(a); }
/// <summary> /// Gets the current value for a given declaration that has necessarily been /// registered at least once. /// </summary> /// <param name="r">The declaration.</param> /// <returns>The current <see cref="RefRuntimeObj"/> to consider.</returns> public RefRuntimeObj FindRegistered(AccessorLetExpr r) { Entry e; if (_vars.TryGetValue(r, out e)) { return((e.Next ?? e).O); } throw new ArgumentException($"Unregistered variable '{r.Name}'."); }
Expr HandleLet() { List <AccessorLetExpr> decl = null; List <Expr> multi = null; for ( ;;) { string name = _parser.ReadIdentifier(); if (name == null) { return(new SyntaxErrorExpr(_parser.Location, "Expected identifier (variable name).")); } var v = new AccessorLetExpr(_parser.PrevNonCommentLocation, name); Expr e = _parser.IsAssignOperator ? HandleAssign(v, _scope.Find(name), name) : v; Debug.Assert(!(e is SyntaxErrorExpr)); if (_parser.Match(TokenizerToken.Comma)) { if (multi == null) { multi = new List <Expr>(); decl = new List <AccessorLetExpr>(); } multi.Add(e); decl.Add(v); } else { Expr reg = _scope.Declare(v); if (reg is SyntaxErrorExpr) { return(reg); } if (multi == null) { return(e); } foreach (var var in decl) { reg = _scope.Declare(var); if (reg is SyntaxErrorExpr) { return(reg); } } multi.Add(e); return(new ListOfExpr(multi)); } } }
public TryCatchExpr(SourceLocation location, Expr tryExpr, AccessorLetExpr exceptionParameter, Expr catchExpr) : base(location, true, true) { if (tryExpr == null) { throw new ArgumentException("tryExpr"); } if (catchExpr == null) { throw new ArgumentNullException("catchExpr"); } TryExpr = tryExpr; ExceptionParameter = exceptionParameter; CatchExpr = catchExpr; }
/// <summary> /// Declares an expression in the current scope. Returns either the given <see cref="AccessorLetExpr"/> /// or a <see cref="SyntaxErrorExpr"/>. /// </summary> /// <param name="name">Name of the expression.</param> /// <param name="e">The expression to register.</param> /// <returns>The expression to register or a syntax error if it can not be registered.</returns> public Expr Declare(string name, AccessorLetExpr e) { if (_firstScope == null) { return(new SyntaxErrorExpr(e.Location, "Invalid declaration (a scope must be opened first).")); } if (_disallowRegistration) { return(new SyntaxErrorExpr(e.Location, "Invalid declaration.")); } var curScope = _firstScope.NextScope ?? _firstScope; NameEntry first, newOne; if (_vars.TryGetValue(name, out first)) { if (first.E == null) { first.E = e; newOne = first; } else { var cur = first.Next ?? first; if (_allowMasking || cur.Scope.StrongScope != _currentStrongScope) { if (_allowLocalRedefinition || cur.Scope != curScope) { first.Next = newOne = new NameEntry(first.Next, e); } else { return(new SyntaxErrorExpr(e.Location, "Declaration of '{1}' conflicts with declaration at {0}.", first.E.Location, e.Name)); } } else { return(new SyntaxErrorExpr(e.Location, "Masking is not allowed: declaration of '{1}' conflicts with declaration at {0}.", first.E.Location, e.Name)); } } } else { _vars.Add(name, (first = newOne = new NameEntry(null, e))); } curScope.Add(newOne, first); return(e); }
/// <summary> /// Unregisters a previously registered local variable, function parameter, or <see cref="Closure"/>. /// </summary> /// <param name="decl">The declaration to unregister.</param> public virtual void Unregister(AccessorLetExpr decl) { Entry e; if (_vars.TryGetValue(decl, out e)) { if (e.Next != null) { e.Next = e.Next.Next; return; } if (e.O != null) { e.O = null; return; } } throw new InvalidOperationException($"Unregistering non registered '{decl.Name}'."); }
public FunctionExpr(SourceLocation location, IReadOnlyList <AccessorLetExpr> parameters, Expr body, IReadOnlyList <AccessorLetExpr> closures, AccessorLetExpr name = null) : base(location, name != null, false) { if (parameters == null) { throw new ArgumentNullException(); } if (body == null) { throw new ArgumentNullException(); } if (closures == null) { throw new ArgumentNullException(); } Parameters = parameters; Name = name; Body = body; Closures = closures; }
/// <summary> /// Registers a local variable or a function parameter. /// Registering multiple times the same locals or parameters means that recursion is at work. /// </summary> /// <param name="local">The local or parameter to register.</param> /// <returns>The unitialized <see cref="RefRuntimeObj"/> (undefined).</returns> public virtual RefRuntimeObj Register(AccessorLetExpr local) { Entry e; if (_vars.TryGetValue(local, out e)) { if (e.O == null) { e.O = new RefRuntimeObj(); } else { e = e.Next = new Entry(e.Next, new RefRuntimeObj()); } } else { _vars.Add(local, e = new Entry(null, new RefRuntimeObj())); } return(e.O); }
T Register <T>(AccessorLetExpr local, T refObj) where T : RefRuntimeObj { Entry e; if (_vars.TryGetValue(local, out e)) { if (e.O == null) { e.O = refObj; } else { e = e.Next = new Entry(e.Next, refObj); } } else { _vars.Add(local, e = new Entry(null, refObj)); } Debug.Assert(e.O == refObj); return(refObj); }
Expr TryRegisterFuncParametersAndOpenBody(bool allowNone) { if (!_parser.Match(JSTokenizerToken.OpenPar)) { if (!allowNone) { return(new SyntaxErrorExpr(_parser.Location, "Expected '('.")); } } else { string pName; while ((pName = _parser.ReadIdentifier()) != null) { AccessorLetExpr param = new AccessorLetExpr(_parser.PrevNonCommentLocation, pName); Expr eRegParam = _scope.Declare(pName, param); if (eRegParam is SyntaxErrorExpr) { return(eRegParam); } if (!_parser.Match(JSTokenizerToken.Comma)) { break; } } if (!_parser.Match(JSTokenizerToken.ClosePar)) { return(new SyntaxErrorExpr(_parser.Location, "Expected ')'.")); } } if (!_parser.Match(JSTokenizerToken.OpenCurly)) { return(new SyntaxErrorExpr(_parser.Location, "Expected '{{}'.")); } return(null); }
/// <summary> /// Registers an indexed variable. /// </summary> /// <param name="local">The local or parameter to register.</param> /// <param name="index">Index of the variable.</param> /// <returns>The unitialized <see cref="RefRuntimeIndexedObj"/> (undefined).</returns> public RefRuntimeIndexedObj Register(AccessorLetExpr local, int index) => Register(local, new RefRuntimeIndexedObj(index));
/// <summary> /// Registers a local variable or a function parameter. /// Registering multiple times the same locals or parameters means that recursion is at work. /// </summary> /// <param name="local">The local or parameter to register.</param> /// <returns>The unitialized <see cref="RefRuntimeObj"/> (undefined).</returns> public RefRuntimeObj Register(AccessorLetExpr local) => Register(local, new RefRuntimeObj());
public NameEntry(NameEntry next, AccessorLetExpr e) { Next = next; E = e; }
/// <summary> /// Initializes a new <see cref="Closure"/>. /// </summary> /// <param name="v">The variable declaration.</param> /// <param name="r">The bound reference.</param> public Closure(AccessorLetExpr v, RefRuntimeObj r) { Variable = v; Ref = r; }
public virtual Expr Visit(AccessorLetExpr e) { return(e); }
public PExpr Visit(AccessorLetExpr e) => new PExpr(ScopeManager.FindRegistered(e));