예제 #1
0
        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));
        }
예제 #2
0
 public ForeachExpr(SourceLocation location, AccessorLetExpr var, Expr generator, Expr code)
     : base(location, true, false)
 {
     Variable  = var;
     Generator = generator;
     Code      = code;
 }
예제 #3
0
        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));
        }
예제 #4
0
 internal void AddClosure(AccessorLetExpr a)
 {
     if (_closures == null)
     {
         _closures = new HashSet <AccessorLetExpr>();
     }
     _closures.Add(a);
 }
예제 #5
0
        /// <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}'.");
        }
예제 #6
0
        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));
                }
            }
        }
예제 #7
0
 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;
 }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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}'.");
        }
예제 #10
0
 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;
 }
예제 #11
0
        /// <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);
        }
예제 #12
0
        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);
        }
예제 #13
0
 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);
 }
예제 #14
0
 /// <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));
예제 #15
0
 /// <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());
예제 #16
0
 public NameEntry(NameEntry next, AccessorLetExpr e)
 {
     Next = next;
     E    = e;
 }
예제 #17
0
 /// <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;
 }
예제 #18
0
 public virtual Expr Visit(AccessorLetExpr e)
 {
     return(e);
 }
예제 #19
0
 public PExpr Visit(AccessorLetExpr e) => new PExpr(ScopeManager.FindRegistered(e));