def __init__(self, position): super(_DelegateCtor, self).__init__( position, params=[ Parameter(position, 'obj', util.getNineType(System.Object)), Parameter(position, 'ftn', util.getNineType(System.IntPtr)) ], body=BlockStatement(), flags=MemberFlags() )
def emitAssign(self, rhs, gen): from nine import util from CLR import System object = util.getNineType(System.Object) value = util.getNineType(System.ValueType) assert self.builder is not None rhs.emitLoad(gen) if self.type == object and value.isDescendant(rhs.getType()): gen.ilGen.Emit(gen.opCodes.Box, rhs.getType().builder) gen.ilGen.Emit(gen.opCodes.Stloc, self.builder)
def getMethod(self, name, paramList, returnType): from ast.functiondecl import FunctionDecl from CLR import System for decl in self.body.decls: if decl.name != name or not isinstance(decl, FunctionDecl): continue # compare argument lists for param, arg in zip(decl.params, paramList): atype = arg.getType() ptype = param.getType() if atype != ptype: return None # compare return types returnType = util.getNineType(returnType) if returnType != decl.returnType: return None # FIXME? no test coverage for this line return decl else: for base in self.bases: m = base.getMethod(name, paramList, returnType) if m is not None: return m return None
def emitLoad(self, gen): object = util.getNineType(System.Object) value = util.getNineType(System.ValueType) ilType = self.type.builder assert ilType is not None, self.type self.arg.emitLoad(gen) if self.type == object and value.isDescendant(self.arg.getType()): #box gen.ilGen.Emit(gen.opCodes.Box, self.arg.getType().builder) elif self.type.builder.IsValueType and self.arg.getType() == object: #unbox gen.ilGen.Emit(gen.opCodes.Unbox, ilType) if self.type == util.getNineType(System.Int32): gen.ilGen.Emit(gen.opCodes.Ldind_I4) elif self.type == util.getNineType(System.Single): gen.ilGen.Emit(gen.opCodes.Ldind_R4) else: assert False, "oh shit! dinosaurs!. Actually we've got some not-primitive value types not getting unboxed." else: #cast to primitive types if self.type == util.getNineType(System.Int32): gen.ilGen.Emit(gen.opCodes.Conv_I4) elif self.type == util.getNineType(System.Single): gen.ilGen.Emit(gen.opCodes.Conv_R4) elif self.type == util.getNineType(System.Double): gen.ilGen.Emit(gen.opCodes.Conv_R8) else: #cast to a class gen.ilGen.Emit(gen.opCodes.Castclass, ilType)
def semantic(self, scope): self.type = self.type.semantic(scope) if not util.getNineType(System.Exception).isParentClass(self.type): raise error.SyntaxError(self.position, "Except argument must be a subclass of System.Exception") if self.name is not None: if self.name in scope: raise error.NameError(self.position, "Identifier %s already declared at %r" % (self.name, scope[self.name].position)) self.variable = vardecl.VarDecl(self.name, self.position, self.type, _ExceptionThingie(self.type)) return self
def semantic(self, scope): lhs = self.base.semantic(scope) rhs = self.exp.semantic(scope) ltype = lhs.getType() rtype = rhs.getType() dbl = util.getNineType(System.Single) if ltype not in legalTypes or rtype not in legalTypes: raise error.TypeError, "exponentiation valid only between %s, not %s and %s" % (legalTypes, ltype, rtype) return ExponentExpression(lhs, rhs)
def __init__(self, position, name, params, returnType): flags = MemberFlags(sealed = True, public = True) self.params = params self.returnType = returnType bases = [util.getNineType(System.MulticastDelegate)] body = classdecl.ClassBody([ _DelegateCtor(position), _InvokeMethod(position, params, returnType) ]) # create func Invoke super(DelegateDecl, self).__init__(position, name, bases, body, flags)
def semantic(self, scope): arg = self.arg.semantic(scope) type = self.type.semantic(scope) argType = arg.getType() # If the arg type and the cast type are the same, the cast is a no-op # Remove it from the code if argType == type: return arg # make sure that arg can be coerced into the type if not type.isDescendant(argType) and not argType.isDescendant(type) and not util.getNineType(System.ValueType).isDescendant(argType): raise error.TypeError(self.position, "Cannot cast expression %r from type %r to %r" % (arg, argType, type)) return CastExpression(self.position, arg, type)
def __checkBases(self, scope): '''If the object doesn't explicitly extend a class, make sure it extends System.Object. Also checks various miscellany with respect to base classes, such as circular inheritance chains, and inheriting things which are not interfaces or classes. ''' from CLR import System from ast.interfacedecl import InterfaceDecl for index, base in enumerate(self.bases): self.bases[index] = base.semantic(scope) Object = util.getNineType(System.Object) for base in self.bases: if isinstance(base, ClassDecl): if self.baseClass is None: self.baseClass = base elif self.baseClass is not base: raise error.OverrideError(self.position, 'Multiple class inheritance is not yet supported') if base.isSubClass(self): raise error.CircularInheritanceError(self.position, 'Circular inheritance between "%s" and "%s"' % (self.name, base.name)) elif isinstance(base, InterfaceDecl): self.baseInterfaces.append(base) else: raise error.OverrideError(self.position, 'Cannot inherit %r, it is not a class or interface' % base) if self.baseClass is None: self.baseClass = Object self.bases.insert(0, Object) if self.baseClass.flags.sealed: raise error.OverrideError(self.position, 'Class %s is sealed and cannot be inherited' % base.name)
def emitCode(self, gen): gen.ilGen.BeginExceptionBlock() self.tryBlock.emitCode(gen) for filter, block in self.exceptBlocks: if filter is None: filterType = util.getNineType(System.Exception) else: filterType = filter.type gen.ilGen.BeginCatchBlock(filterType.builder) if filter is None or filter.name is None: gen.ilGen.Emit(gen.opCodes.Pop) block.emitCode(gen) if self.finallyBlock is not None: gen.ilGen.BeginFinallyBlock() self.finallyBlock.emitCode(gen) gen.ilGen.EndExceptionBlock()
def semantic(self, *args): from nine import util return util.getNineType(self.type)
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)
from ast import vartypes from nine import lexer from nine import error from nine import util from CLR import System import clr legalTypes = [util.getNineType(t) for t in [System.Int32, System.Single, System.Double]] class ExponentExpression(object): def __init__(self, base, exp): self.base =base self.exp = exp def getType(self): ltype = self.base.getType() rtype = self.exp.getType() return legalTypes[max(legalTypes.index(ltype), legalTypes.index(rtype))] def parse(tokens): from ast.unaryexpression import UnaryExpression expr = UnaryExpression.parse(tokens) if expr is None: return None while True: pos = tokens.getPosition() if tokens.peek() == '**':