Example #1
0
    def parse(tokens):
        if tokens.peek() is not token.BEGIN_BLOCK:
            return None

        attributes = []
        decls = []

        tokens.expect(token.BEGIN_BLOCK)
        while tokens.peek() is not token.END_BLOCK:
            decl = None

            attr = Attribute.parse(tokens)
            if attr is not None:
                attributes.append(attr)
            else:
                decl = (
                    FunctionDecl.parse(tokens) or
                    VarDecl.parse(tokens) or
                    PassStatement.parse(tokens)
                )

                if decl is None:
                    raise error.SyntaxError(tokens.peek().position, 'Expected end block, variable or class declaration, or pass statement.  Got %r' % tokens.peek())

                if not isinstance(decl, PassStatement):
                    decls.append(decl)

            while tokens.peek() is token.END_OF_STATEMENT:
                tokens.getNext()

        tokens.expect(token.END_BLOCK)

        return ClassBody(decls, attributes)
Example #2
0
    def testSemantic(self):
        tokens = lex('var x as int')
        scope = Scope(parent=None)

        decl = VarDecl.parse(tokens)
        result = decl.semantic(scope)
        self.failUnless(isinstance(result, VarDecl), result)
        self.failUnless('x' in scope)

        # x is already defined in the scope, this should fail, as it is a duplicate
        self.failUnlessRaises(Exception,
            lambda: tokens.semantic(scope)
        )
    def semantic(self, scope):
        '''
        Slightly nasty.  We do an AST replacement here, turning the for loop
        into an equivalent while loop using an IEnumerator instance.

        Long story short, this:

            for iterator as T in y:
                stmts

        becomes this:

            var _e = y.GetEnumerator()
            while _e.MoveNext():
                var iterator = _e.Current as T
                stmts
        '''

        from ast.blockstatement import BlockStatement
        from ast.whilestatement import WhileStatement
        from ast.assignstatement import AssignStatement
        from ast.castexpression import CastExpression
        from ast.arraytype import ArrayType
        from ast.vardecl import VarDecl
        from nine.scope import Scope

        IEnumerator = util.getNineType(System.Collections.IEnumerator)
        Object = util.getNineType(System.Object)
        Boolean = util.getNineType(System.Boolean)

        elementType = Object

        sequence = self.sequence.semantic(scope)
        seqType = sequence.getType()

        if isinstance(seqType, ArrayType):
            elementType = seqType.arrayType
        elif self.iterator.type is not None:
            elementType = self.iterator.type

        enumerator = VarDecl('$$$ secret enumerator 0x%08X $$$' % id(self), self.position, IEnumerator,
            initializer=seqType.getMember(sequence, 'GetEnumerator').apply(())
        )

        miniScope = Scope(parent=scope)

        enumerator = enumerator.semantic(miniScope)

        # var iterator = enumerator.get_Current() as ElementType
        assert self.iterator.initializer is None, self
        self.iterator.initializer = CastExpression(self.position, IEnumerator.getMember(enumerator, 'get_Current').apply(()), elementType)

        # Finally, create the new replacement AST, do the usual semantic
        # testing on it, and return it as a replacement for our ForStatement
        # expression.
        return BlockStatement((
            enumerator,
            WhileStatement(
                IEnumerator.getMember(enumerator, 'MoveNext').apply(()),

                BlockStatement((
                    self.iterator,
                    self.body,
                ))
            )
        )).semantic(miniScope)
Example #4
0
    def testBadParse(self):
        tokens = lex('var 42')

        self.failUnlessRaises(error.SyntaxError,
            lambda: VarDecl.parse(tokens)
        )
Example #5
0
    def testInitializer(self):
        tokens = lex('var x = 291')

        result = VarDecl.parse(tokens)
        assert isinstance(result, VarDecl), result
Example #6
0
    def testTypeDefinition(self):
        tokens = lex('var x as int')

        VarDecl.parse(tokens)
Example #7
0
    def testFailParse(self):
        tokens = lex('print 4')

        result = VarDecl.parse(tokens)
        self.failUnless(result is None, result)
Example #8
0
    def testGoodParse(self):
        tokens = lex('var foo')

        result = VarDecl.parse(tokens)
        self.failUnless(isinstance(result, VarDecl), result)