Example #1
0
func printPackage(p *tp.Package, indLvl int) {
	printIndent("Name -> %v", indLvl, p.GetName())
	printIndent("Path -> %v", indLvl, p.GetPath())
	printIndent("Dependencies:", indLvl)
	for ind, item := range p.GetDependencies() {
		printIndent("Dependecny[%v] -> %v", indLvl+1, ind, item)
	}
	printIndent("Types:", indLvl)
	for ind, item := range p.GetTypes() {
		printIndent("Type[%v] -> %v", indLvl+1, ind, item)
	}
	printIndent("Functions:", indLvl)
	for ind, item := range p.GetFunctions() {
		printIndent("Function[%v]:", indLvl+1, ind)
		printFunction(item, indLvl+2)
	}
}
Example #2
0
func NewLinkingContext(pkg *tp.Package) *LinkingContext {
	// Setup the function map!
	functionLookup := make([]FuncMap, len(pkg.Types))
	types := make([]string, len(pkg.Types))

	for typeId, typeObj := range pkg.Types {
		funcMap := make(FuncMap)
		types[typeId] = typeObj.GetName()
		implements := functionLookup[typeObj.GetImplements()]
		for index, fun := range pkg.Functions {
			stub := fun.Stub(pkg)

			funScopeId := fun.GetScopeTypeId()
			inherited := false
			// funScopeId is ancestor of typeId
			if (implements != nil) && pkg.AncestorOf(funScopeId, int32(typeId)) {
				_, inherited = implements[stub]
			}
			if (funScopeId == int32(typeId)) || inherited {
				funcMap[stub] = index
			}
		}
		functionLookup[typeId] = funcMap
	}

	// Setup the main context object
	ctx := &LinkingContext{
		funList: functionLookup,
		types:   types,
		Errors:  make([]string, 0),
		Transform: &tp.Transform{
			Pkg: pkg,
		},
	}

	// Find Text type int -- need its ID to deal with Text literals during processing
	ctx.textType = pkg.GetTypeId("Text")

	return ctx
}
Example #3
0
func ancestralFuncStub(pkg *tp.Package, fun *tp.Function) *string {
	foundAncestor := false

	name := null.GetString(fun.Name)
	args := ""
	for _, arg := range fun.Args {
		argType := null.GetInt32(arg.TypeId)
		ancestralArgType := FindAncestralType(pkg, argType)

		if ancestralArgType != -1 {
			foundAncestor = true
			argType = ancestralArgType
		}

		argTypeString := pkg.GetTypeName(argType)

		argName := argTypeString
		argName = argName + " %" + null.GetString(arg.Name)
		args = args + ", " + argName
	}
	if len(args) > 1 {
		args = args[2:]
	}

	returnType := null.GetInt32(fun.ReturnTypeId)
	ancestralReturnType := FindAncestralType(pkg, returnType)

	if ancestralReturnType != -1 {
		foundAncestor = true
		returnType = ancestralReturnType
	}

	returnTypeString := pkg.GetTypeName(returnType)
	returnVal := name + "(" + args + ") " + returnTypeString + " "

	opensType := null.GetInt32(fun.OpensTypeId)
	ancestralOpensType := FindAncestralType(pkg, opensType)

	if ancestralOpensType != -1 {
		foundAncestor = true
		opensType = ancestralOpensType
	}

	opensTypeString := pkg.GetTypeName(opensType)

	if opensTypeString != "Base" {
		returnVal = returnVal + opensTypeString
	}

	if foundAncestor {
		return &returnVal
	}
	return nil

}
Example #4
0
func resolveDefinition(pkg *tp.Package, fun *tp.Function, path string) {
	linkingContext := linker.NewLinkingContext(pkg)

	//	pkg.Log.Infof("\t -- Resolving --\n")
	//	pkg.Log.Infof("\t\t -- function: %v\n", fun)

	// Re-uses linker's logic to resolve function definitions
	if null.GetBool(fun.BuiltIn) == false {
		typeName := null.GetString(fun.ScopeType)

		// DON'T DO THE FOLLOWING HERE -- NEED TO RESOLVE INHERITANCE FIRST
		// // Make sure we're not replacing an existing function bacause it's (currently) a security risk
		// typeID := fun.GetScopeTypeId()
		// siblingFuncs := linkingContext.FunctionsIn(typeID)
		// // println("CHECKING FOR FRATRICIDE IN", typeName)
		// _, present := siblingFuncs[fun.Stub(pkg)]
		// if present {
		// 	msg := fmt.Sprintf("Redefining an existing function is not permitted: %s", fun.Stub(pkg))
		// 	panic(msg)
		// }
		// // for name, sib := range siblingFuncs {
		// // 	println("\t", name, sib)
		// // }
		// /////////////////////////////////////////////////////////////////////////////

		if len(typeName) != 0 {
			// When I pass in functions from the inheritance resolver, they're typeId is already set
			fun.ScopeTypeId = pkg.GetProtoTypeId(fun.ScopeType)
			fun.ScopeType = nil
		}

		localScope := make(linker.LocalDef, len(fun.Args))

		//		fun.ReturnTypeId = pkg.GetProtoTypeId(fun.ReturnType)
		for _, arg := range fun.Args {
			argTypeName := arg.TypeString
			var argTypeId int

			if argTypeName != nil {
				// Similar deal. Input functions from inheritance resolution already have ids set

				arg.TypeId = pkg.GetProtoTypeId(arg.TypeString)
				//println("Processing %", null.GetString(arg.Name))
				argTypeId = pkg.GetTypeId(null.GetString(arg.TypeString))
				arg.TypeString = nil
			} else {
				argTypeId = int(null.GetInt32(arg.TypeId))
			}

			localScope[null.GetString(arg.Name)] = argTypeId
		}

		//pkg.Log.Infof("Some insitruction: %v, %s", fun.Instruction, null.GetString(fun.Name) )
		scopeTypeId := int(null.GetInt32(fun.ScopeTypeId))
		//pkg.Log.Infof("\t\t -- opening scope type : %v\n", scopeTypeId)
		returnType := linkingContext.ProcessInstructionWithLocalScope(fun.Instruction, scopeTypeId, localScope, *fun.Name, path, false)

		if linkingContext.HasErrors() {
			message := ""
			for _, msg := range linkingContext.Errors {
				message = message + "\n" + msg
			}
			panic(message)
		}

		fun.ReturnTypeId = proto.Int32(int32(returnType))
		if fun.Instruction != nil {
			fun.Instruction.IterateAll(func(ins *tp.Instruction) {
				if *ins.Type == constants.Instruction_FUNCTION_CALL {
					if null.GetString(ins.Value) == "yield" {
						fun.OpensTypeId = ins.YieldTypeId
					}
				}
			})
		}

	}
	//pkg.Log.Infof("\t\t -- done --\n")
}
Example #5
0
func ReadPackageDefinitions(pkg *tp.Package, projectPath, scriptPath, fileName string) {
	//pkg.Println(" -- reading definitions")
	_, err := ioutil.ReadFile(filepath.Join(projectPath, scriptPath, fileName))
	//()("READING DEFINITIONS:", location)

	if err != nil {
		//pkg.Log.Infof("\t -- no user defined functions found")
		// msg := fmt.Sprintf("unable to open function definition file: %s", location)
		// println(msg)
		// panic(msg)
		return
	}
	definitions := parser.ParseFile(projectPath, scriptPath, fileName, false, make([]string, 0))

	// Create a map of pre-packaged function signatures
	prepackaged := make(map[string]bool)
	for _, f := range pkg.Functions {
		var sig string
		baseSig := f.Stub(pkg)
		if baseSig == "name,Text" ||
			baseSig == "text" {
			sig = fmt.Sprintf("%s.%s", f.ScopeTypeString(pkg), f.Stub(pkg))
		} else {
			sig = baseSig
		}
		prepackaged[sig] = true
	}
	// println("*****************")
	// println("*****************")
	// println()
	// println()

	for _, function := range definitions.Functions {
		if function.GetName() == "@import" { // check if it's an import stub first ...
			importPath := function.GetDescription()
			// Verify the existence of the imported file from here, so that we can
			// report the name of the file that contains the import statement.
			importExists, existsErr := exists(filepath.Join(projectPath, importPath))
			if !importExists || (existsErr != nil) {
				errURL := "http://help.moovweb.com/entries/22335641-importing-non-existent-files-in-functions-main-ts"
				msg := fmt.Sprintf("\n********\nin file %s:\nattempting to import nonexistent file %s\nPlease consult %s for more information about this error.\n********\n", filepath.Join(scriptPath, fileName), importPath, errURL)
				panic(msg)
			}
			ReadPackageDefinitions(pkg, projectPath, filepath.Dir(importPath), filepath.Base(importPath))
		} else { // otherwise if it's not an import stub ...
			//pkg.Log.Infof("\t -- function: %v", function)
			resolveDefinition(pkg, function, filepath.Join(scriptPath, fileName))

			// After resolving a user-defined function, see if its fully resolved signature
			// is the same as the signature of a prepackaged function. If so, throw an error.
			// var newSig string
			// newBaseSig := function.Stub(pkg)
			// if newBaseSig == "name,Text" ||
			// 	newBaseSig == "text" {
			// 	newSig = fmt.Sprintf("%s.%s", function.ScopeTypeString(pkg), function.Stub(pkg))
			// } else {
			// 	newSig = newBaseSig
			// }
			// // present := false
			// _, present := prepackaged[newSig]
			// if present {
			// 	msg := fmt.Sprintf("Attempt to redefine prepackaged function: %s", strings.Replace(newSig, ",", "(", 1)+")")
			// 	println(msg)
			// 	panic(msg)
			// }

			pkg.Functions = append(pkg.Functions, function)
		}
	}

}