/// <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; }
public void declaring_while_no_scope_is_opened_is_a_syntax_error() { StaticScope s = new StaticScope(); var v = new AccessorLetExpr(SourceLocation.Empty, "V"); Assert.IsInstanceOf <SyntaxErrorExpr>(s.Declare("toto", v)); s.OpenScope(); Assert.AreSame(s.Declare("toto", v), v); Assert.AreSame(s.Find("toto"), v); CheckClose(s.CloseScope(), "V"); Assert.IsInstanceOf <SyntaxErrorExpr>(s.Declare("toto", v)); }
public void declaring_while_no_scope_is_opened_is_a_syntax_error() { StaticScope s = new StaticScope(); var v = new AccessorLetExpr(SourceLocation.Empty, "V"); s.Declare(v).Should().BeOfType <SyntaxErrorExpr>(); s.OpenScope(); s.Declare(v).Should().BeSameAs(v); s.Find("V").Should().BeSameAs(v); CheckClose(s.CloseScope(), v); s.Declare(v).Should().BeOfType <SyntaxErrorExpr>(); }
public void redefinition_in_the_same_scope_is_not_allowed_by_default() { StaticScope s = new StaticScope(); var v = new AccessorLetExpr(SourceLocation.Empty, "V"); var v1 = new AccessorLetExpr(SourceLocation.Empty, "V (redefined)"); var v2 = new AccessorLetExpr(SourceLocation.Empty, "V (redefined again)"); var vFailed = new AccessorLetExpr(SourceLocation.Empty, "V (failed)"); s.OpenScope(); Assert.AreSame(s.Declare("V", v), v); Assert.IsInstanceOf <SyntaxErrorExpr>(s.Declare("V", vFailed)); s.AllowLocalRedefinition = true; Assert.AreSame(s.Declare("V", v1), v1); Assert.AreSame(s.Declare("V", v2), v2); s.AllowLocalRedefinition = false; Assert.IsInstanceOf <SyntaxErrorExpr>(s.Declare("V", vFailed)); CheckClose(s.CloseScope(), "V", "V (redefined)", "V (redefined again)"); }
public void redefinition_in_the_same_scope_is_not_allowed_by_default() { StaticScope s = new StaticScope(); var v = new AccessorLetExpr(SourceLocation.Empty, "V"); var v1 = new AccessorLetExpr(SourceLocation.Empty, "V"); var v2 = new AccessorLetExpr(SourceLocation.Empty, "V"); var vFailed = new AccessorLetExpr(SourceLocation.Empty, "V"); s.OpenScope(); s.Declare(v).Should().BeSameAs(v); s.Declare(vFailed).Should().BeOfType <SyntaxErrorExpr>(); s.AllowLocalRedefinition = true; s.Declare(v1).Should().BeSameAs(v1); s.Declare(v2).Should().BeSameAs(v2); s.AllowLocalRedefinition = false; s.Declare(vFailed).Should().BeOfType <SyntaxErrorExpr>(); CheckClose(s.CloseScope(), v, v1, v2); }
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; }
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 ); }
/// <summary> /// Gets the current value for a given declaration that must have 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( String.Format( "Unregistered variable '{0}'.", r.Name ) ); }
/// <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( String.Format( "Unregistering non registered '{0}'.", decl.Name ) ); }
public void redefinition_in_the_same_scope_is_not_allowed_by_default() { StaticScope s = new StaticScope(); var v = new AccessorLetExpr( SourceLocation.Empty, "V" ); var v1 = new AccessorLetExpr( SourceLocation.Empty, "V (redefined)" ); var v2 = new AccessorLetExpr( SourceLocation.Empty, "V (redefined again)" ); var vFailed = new AccessorLetExpr( SourceLocation.Empty, "V (failed)" ); s.OpenScope(); Assert.AreSame( s.Declare( "V", v ), v ); Assert.IsInstanceOf<SyntaxErrorExpr>( s.Declare( "V", vFailed ) ); s.AllowLocalRedefinition = true; Assert.AreSame( s.Declare( "V", v1 ), v1 ); Assert.AreSame( s.Declare( "V", v2 ), v2 ); s.AllowLocalRedefinition = false; Assert.IsInstanceOf<SyntaxErrorExpr>( s.Declare( "V", vFailed ) ); CheckClose( s.CloseScope(), "V", "V (redefined)", "V (redefined again)" ); }
public void declaring_while_no_scope_is_opened_is_a_syntax_error() { StaticScope s = new StaticScope(); var v = new AccessorLetExpr( SourceLocation.Empty, "V" ); Assert.IsInstanceOf<SyntaxErrorExpr>( s.Declare( "toto", v ) ); s.OpenScope(); Assert.AreSame( s.Declare( "toto", v ), v ); Assert.AreSame( s.Find( "toto" ), v ); CheckClose( s.CloseScope(), "V" ); Assert.IsInstanceOf<SyntaxErrorExpr>( s.Declare( "toto", v ) ); }