<s> import ufora . FORA . python . ParseException as ParseException <EOL> import ufora . FORA . python . ForaValue as ForaValue <EOL> import ufora . native . FORA as ForaNative <EOL> def freshVarname ( startingName , namesUsed ) : <EOL> """<STR_LIT>""" <EOL> if startingName not in namesUsed : <EOL> return startingName <EOL> ix = <NUM_LIT:1> <EOL> while True : <EOL> name = startingName + "<STR_LIT:_>" + str ( ix ) <EOL> if name not in namesUsed : <EOL> return name <EOL> ix = ix + <NUM_LIT:1> <EOL> class NameExistsButDoesntParseException ( object ) : <EOL> def __init__ ( self , projectNode , name ) : <EOL> self . projectNode = projectNode <EOL> self . name = name <EOL> @ property <EOL> def childrenWhoDontParse ( self ) : <EOL> return self . projectNode . childrenWhoDontParse <EOL> class Expression ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , nativeExpression , codeDefinitionPoint ) : <EOL> assert isinstance ( nativeExpression , ForaNative . Expression ) <EOL> self . nativeExpression_ = nativeExpression <EOL> self . codeDefinitionPoint_ = codeDefinitionPoint <EOL> freeVariables = property ( lambda self : self . nativeExpression_ . freeVariables ) <EOL> mentionedVariables = property ( lambda self : self . nativeExpression_ . mentionedVariables ) <EOL> assignedVariables = property ( lambda self : self . nativeExpression_ . assignedVariables ) <EOL> freeVariableMemberAccesses = property ( lambda self : <EOL> self . nativeExpression_ . freeVariableMemberAccesses ) <EOL> def packAssignedVarsIntoTuple ( self ) : <EOL> """<STR_LIT>""" <EOL> return Expression ( self . nativeExpression_ . packAssignedVarsIntoTuple ( ) , self . codeDefinitionPoint_ ) <EOL> def freeVariableUsePoints ( self , varname ) : <EOL> """<STR_LIT>""" <EOL> return self . nativeExpression_ . getFreeVariableRanges ( varname ) <EOL> def getReturnStatementPoints ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . nativeExpression_ . getReturnStatementRanges ( ) <EOL> def assignedVariableUsePoints ( self , varname ) : <EOL> """<STR_LIT>""" <EOL> return self . nativeExpression_ . getAssignedVariableRanges ( varname ) <EOL> def toFunction ( self ) : <EOL> """<STR_LIT>""" <EOL> return ForaValue . FORAValue ( self . nativeExpression_ . toFunctionImplval ( False ) ) <EOL> def toFunctionAsImplval ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . nativeExpression_ . toFunctionImplval ( False ) <EOL> def toFunctionAsImplvalWithPassthroughArgument ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . nativeExpression_ . toFunctionImplvalWithPassthroughArgument ( False ) <EOL> def rebindFreeVariableMemberAccess ( self , varname , memberName , newName ) : <EOL> """<STR_LIT>""" <EOL> return Expression ( <EOL> self . nativeExpression_ . rebindFreeVariableMemberAccess ( <EOL> varname , <EOL> memberName , <EOL> newName <EOL> ) , <EOL> self . codeDefinitionPoint_ <EOL> ) <EOL> def raiseParseException_ ( self , functionParseError ) : <EOL> raise ParseException . ParseException ( <EOL> functionParseError , <EOL> self . codeDefinitionPoint_ <EOL> ) <EOL> def raiseIfUsesUndefinedVariables ( self , knownVariables ) : <EOL> for variable in self . assignedVariables : <EOL> self . checkVariableInKnownVariables ( variable , knownVariables ) <EOL> def checkVariableInKnownVariables ( self , variable , knownVariables ) : <EOL> if variable not in knownVariables : <EOL> assignmentLocations = self . assignedVariableUsePoints ( variable ) <EOL> assert assignmentLocations , "<STR_LIT>" % ( variable , str ( self ) ) <EOL> self . raiseParseException_ ( <EOL> ForaNative . FunctionParseError ( <EOL> "<STR_LIT>" + variable , <EOL> assignmentLocations [ <NUM_LIT:0> ] . range <EOL> ) <EOL> ) <EOL> def raiseParseErrorIfHasReturnStatements ( self ) : <EOL> getReturnStatementPoints = self . getReturnStatementPoints ( ) <EOL> if getReturnStatementPoints : <EOL> self . raiseParseException_ ( <EOL> ForaNative . FunctionParseError ( <EOL> "<STR_LIT>" , <EOL> getReturnStatementPoints [ <NUM_LIT:0> ] . range <EOL> ) <EOL> ) <EOL> def specializeFreeVariableMapping ( self , <EOL> freeVariableMapping , <EOL> specializationFunc , <EOL> lookupFunc , <EOL> finalVariableValueValidator <EOL> ) : <EOL> """<STR_LIT>""" <EOL> done = False <EOL> checkedNames = set ( ) <EOL> expr = self <EOL> dotSequences = { } <EOL> for varname in self . freeVariables : <EOL> dotSequences [ varname ] = varname <EOL> if varname not in freeVariableMapping : <EOL> varValue = lookupFunc ( varname ) <EOL> if varValue is None : <EOL> codeLocations = self . freeVariableUsePoints ( varname ) <EOL> raise ParseException . ParseException ( <EOL> ForaNative . FunctionParseError ( <EOL> "<STR_LIT>" % ( varname , ) , <EOL> codeLocations [ <NUM_LIT:0> ] . range <EOL> ) , <EOL> self . codeDefinitionPoint_ <EOL> ) <EOL> elif isinstance ( varValue , NameExistsButDoesntParseException ) : <EOL> raise ParseException . ParseException ( <EOL> ForaNative . FunctionParseError ( <EOL> "<STR_LIT>" , <EOL> self . freeVariableUsePoints ( varname ) [ <NUM_LIT:0> ] . range <EOL> ) , <EOL> self . codeDefinitionPoint_ <EOL> ) <EOL> freeVariableMapping [ varname ] = varValue <EOL> while not done : <EOL> done = True <EOL> freeVariablesBound = expr . freeVariableMemberAccesses <EOL> for varname , memberName in freeVariablesBound : <EOL> if varname not in freeVariableMapping : <EOL> freeVariableMapping [ varname ] = lookupFunc ( varname ) <EOL> mapsTo = freeVariableMapping [ varname ] <EOL> if ( mapsTo is not None and varname not in checkedNames ) : <EOL> subNode = specializationFunc ( mapsTo , memberName ) <EOL> if subNode is not None : <EOL> newName = freshVarname ( varname + "<STR_LIT:_>" + memberName , set ( expr . mentionedVariables ) ) <EOL> dotSequences [ newName ] = dotSequences [ varname ] + "<STR_LIT:.>" + memberName <EOL> expr = expr . rebindFreeVariableMemberAccess ( varname , memberName , newName ) <EOL> freeVariableMapping [ newName ] = subNode <EOL> done = False <EOL> else : <EOL> checkedNames . add ( varname ) <EOL> for var in expr . freeVariables : <EOL> errString = finalVariableValueValidator ( freeVariableMapping [ var ] , dotSequences [ var ] ) <EOL> if errString is not None : <EOL> raise ParseException . ParseException ( <EOL> ForaNative . FunctionParseError ( <EOL> errString , <EOL> expr . freeVariableUsePoints ( var ) [ <NUM_LIT:0> ] . range <EOL> ) , <EOL> self . codeDefinitionPoint_ <EOL> ) <EOL> return expr <EOL> def returnFreeVariableValues ( self , locals , importFunction ) : <EOL> """<STR_LIT>""" <EOL> boundVariables = [ ] <EOL> for freeVariable in self . freeVariables : <EOL> if freeVariable in locals : <EOL> boundVariables += [ locals [ freeVariable ] ] <EOL> else : <EOL> binding = importFunction ( freeVariable ) <EOL> if binding is None : <EOL> raise ParseException . ParseException ( <EOL> ForaNative . FunctionParseError ( <EOL> "<STR_LIT>" % freeVariable , <EOL> self . freeVariableUsePoints ( freeVariable ) [ <NUM_LIT:0> ] . range <EOL> ) , <EOL> self . codeDefinitionPoint_ <EOL> ) <EOL> else : <EOL> boundVariables += [ binding ] <EOL> return boundVariables <EOL> @ staticmethod <EOL> def parse ( textToParse , codeDefinitionPoint = None , nameScope = "<STR_LIT>" , parseAsModule = False ) : <EOL> """<STR_LIT>""" <EOL> if codeDefinitionPoint is None : <EOL> codeDefinitionPoint = ForaNative . CodeDefinitionPoint . ExternalFromStringList ( <EOL> [ nameScope ] <EOL> ) <EOL> if parseAsModule : <EOL> nativeExpressionOrParseError = ForaNative . parseObjectDefinitionBodyToExpression ( <EOL> textToParse , <EOL> [ "<STR_LIT>" , nameScope + "<STR_LIT>" ] , <EOL> False , <EOL> nameScope , <EOL> nameScope <EOL> ) <EOL> else : <EOL> nativeExpressionOrParseError = ForaNative . parseStringToExpression ( <EOL> textToParse , <EOL> codeDefinitionPoint , <EOL> nameScope <EOL> ) <EOL> if isinstance ( nativeExpressionOrParseError , ForaNative . FunctionParseError ) : <EOL> raise ParseException . ParseException ( <EOL> nativeExpressionOrParseError , <EOL> codeDefinitionPoint <EOL> ) <EOL> return Expression ( nativeExpressionOrParseError , codeDefinitionPoint ) <EOL> def __str__ ( self ) : <EOL> return str ( self . nativeExpression_ ) </s>
