def returnFreeVariableValues(self, locals, importFunction): """Return arguments for the free variables in expression. importFunction = a function to call with free symbols that aren't in locals to look them up """ boundVariables = [] for freeVariable in self.freeVariables: if freeVariable in locals: boundVariables += [locals[freeVariable]] else: binding = importFunction(freeVariable) if binding is None: raise ParseException.ParseException( ForaNative.FunctionParseError( "Couldn't resolve free variable '%s'" % freeVariable, self.freeVariableUsePoints(freeVariable)[0].range), self.codeDefinitionPoint_) else: boundVariables += [binding] return boundVariables
def raiseParseErrorIfHasReturnStatements(self): getReturnStatementPoints = self.getReturnStatementPoints() if getReturnStatementPoints: self.raiseParseException_( ForaNative.FunctionParseError( "can't use a return statement in a command-line expression", getReturnStatementPoints[0].range))
def fromModuleParseError(parseError): return ParseException( ForaNative.FunctionParseError( parseError.error, parseError.location.range ), parseError.location.defPoint )
def fromMessageAndCodeLocation(message, codeLocation): return ParseException( ForaNative.FunctionParseError( message, codeLocation.range ), codeLocation.defPoint )
def checkVariableInKnownVariables(self, variable, knownVariables): if variable not in knownVariables: assignmentLocations = self.assignedVariableUsePoints(variable) assert assignmentLocations, "Can't find assignment point for %s in '%s'." % ( variable, str(self)) self.raiseParseException_( ForaNative.FunctionParseError( "can't assign to free variable " + variable, assignmentLocations[0].range))
def importModuleFromMDS( mds, directory, fname, searchForFreeVariables=False, allowPrivate=False, moduleImportParentList=None, pathToCodeDefinitionStrings=lambda path: ["ModuleImporter", path]): if moduleImportParentList is None: moduleImportParentList = () importExpr, memberType = convertMDSToCreateObjectExpression( mds, os.path.join(directory, fname), allowPrivate, fname, pathToCodeDefinitionStrings) freeVars = importExpr.freeVariables freeVarDefs = {} if searchForFreeVariables: for f in freeVars: freeVarDefs[f] = importModuleAndMemberByName( f, moduleImportParentList) for f in freeVars: if f not in freeVarDefs or freeVarDefs[f] is None: codeLocation = importExpr.computeFreeVariableLocations(f)[0] raise ParseException.ParseException( ForaNative.FunctionParseError( "Couldn't resolve free variable '%s'" % f, codeLocation.range), codeLocation.defPoint) parser = ForaNative.ModuleParser() result = parser.bind(importExpr, freeVarDefs, False) assert result.isModule() assert result.asModule.result is not None return result.asModule.result
def convertMDSToCreateObjectExpression(mds, path, allowPrivate, name, pathToCodeDefinitionStrings): """given an MDS and a path, return an expression that creates a module member and the type of module member.""" tree = convertMDSToSourceCodeTree(mds, name) parser = ForaNative.ModuleParser() result = parser.parse( tree, allowPrivate, ForaNative.CodeDefinitionPoint.ExternalFromStringList( pathToCodeDefinitionStrings(path))) if len(result.errors) == 0: return result, symbol_package error = result.errors[0] raise ParseException.ParseException( ForaNative.FunctionParseError(error.error, error.location.range), error.location.defPoint)
def specializeFreeVariableMapping(self, freeVariableMapping, specializationFunc, lookupFunc, finalVariableValueValidator): """Allow an expression containing expressions like 'm.x' to be specialized. If we know what 'm' binds to, and specializationFunc(freeVariableMapping[m], 'x') produces a non-null value, we rebind the free variable to a new name with the result of specialzationFunc. Finally, we call 'finalVariableValueValidator' with the value each variable chain has been resolved to, along with a string of dot-separated identifiers. This function should return an error string if the intermediate value that has been bound is invalid. """ done = False checkedNames = set() expr = self dotSequences = {} # Search through all the free variables and look up their values using the given lookup # function. for varname in self.freeVariables: dotSequences[varname] = varname if varname not in freeVariableMapping: varValue = lookupFunc(varname) if varValue is None: codeLocations = self.freeVariableUsePoints(varname) raise ParseException.ParseException( ForaNative.FunctionParseError( "Couldn't resolve free variable '%s'" % (varname, ), codeLocations[0].range), self.codeDefinitionPoint_) elif isinstance(varValue, NameExistsButDoesntParseException): raise ParseException.ParseException( ForaNative.FunctionParseError( "Some modules did not parse correctly.", self.freeVariableUsePoints(varname)[0].range), self.codeDefinitionPoint_) freeVariableMapping[varname] = varValue while not done: done = True #freeVariables = expr.freeVariables freeVariablesBound = expr.freeVariableMemberAccesses for varname, memberName in freeVariablesBound: if varname not in freeVariableMapping: freeVariableMapping[varname] = lookupFunc(varname) mapsTo = freeVariableMapping[varname] if (mapsTo is not None and varname not in checkedNames): subNode = specializationFunc(mapsTo, memberName) if subNode is not None: #we can bind this value to the node newName = freshVarname(varname + "_" + memberName, set(expr.mentionedVariables)) dotSequences[ newName] = dotSequences[varname] + "." + memberName expr = expr.rebindFreeVariableMemberAccess( varname, memberName, newName) freeVariableMapping[newName] = subNode done = False else: checkedNames.add(varname) for var in expr.freeVariables: errString = finalVariableValueValidator(freeVariableMapping[var], dotSequences[var]) if errString is not None: raise ParseException.ParseException( ForaNative.FunctionParseError( errString, expr.freeVariableUsePoints(var)[0].range), self.codeDefinitionPoint_) return expr