Esempio n. 1
0
func LoadRuntime() *ast.Module {
	runtimeModule := &ast.Module{
		Name: &ast.ModuleName{
			Parts: []string{"__runtime"},
		},
		Dirpath: "__runtime",
		Parts:   make(map[string]*ast.Submodule),
	}

	sourcefile := &lexer.Sourcefile{
		Name:     "runtime",
		Path:     "runtime.ark",
		Contents: []rune(RuntimeSource),
		NewLines: []int{-1, -1},
	}
	lexer.Lex(sourcefile)

	tree, deps := parser.Parse(sourcefile)
	if len(deps) > 0 {
		panic("INTERNAL ERROR: No dependencies allowed in runtime")
	}
	runtimeModule.Trees = append(runtimeModule.Trees, tree)

	ast.Construct(runtimeModule, nil)
	ast.Resolve(runtimeModule, nil)

	for _, submod := range runtimeModule.Parts {
		ast.Infer(submod)
	}

	semantic.SemCheck(runtimeModule, *ignoreUnused)

	ast.LoadRuntimeModule(runtimeModule)

	return runtimeModule
}
Esempio n. 2
0
func (v *Context) parseFiles() {
	if strings.HasSuffix(v.Input, ".ark") {
		// Handle the special case of a single .ark file
		modname := &ast.ModuleName{Parts: []string{"__main"}}
		module := &ast.Module{
			Name:    modname,
			Dirpath: "",
		}
		v.moduleLookup.Create(modname).Module = module

		v.parseFile(v.Input, module)

		v.modules = append(v.modules, module)
	} else {
		if strings.ContainsAny(v.Input, `\/. `) {
			setupErr("Invalid module name: %s", v.Input)
		}

		modname := &ast.ModuleName{Parts: strings.Split(v.Input, "::")}
		v.modulesToRead = append(v.modulesToRead, modname)
	}

	log.Timed("read/lex/parse phase", "", func() {
		for i := 0; i < len(v.modulesToRead); i++ {
			modname := v.
				modulesToRead[i]

			// Skip already loaded modules
			if _, err := v.moduleLookup.Get(modname); err == nil {
				continue
			}

			fi, dirpath, err := v.findModuleDir(modname.ToPath())
			if err != nil {
				setupErr("Couldn't find module `%s`: %s", modname, err)
			}

			if !fi.IsDir() {
				setupErr("Expected path `%s` to be directory, was file.", dirpath)
			}

			module := &ast.Module{
				Name:    modname,
				Dirpath: dirpath,
			}
			v.moduleLookup.Create(modname).Module = module

			// Check module children
			childFiles, err := ioutil.ReadDir(dirpath)
			if err != nil {
				setupErr("%s", err.Error())
			}

			for _, childFile := range childFiles {
				if strings.HasPrefix(childFile.Name(), ".") || !strings.HasSuffix(childFile.Name(), ".ark") {
					continue
				}

				actualFile := filepath.Join(dirpath, childFile.Name())
				v.parseFile(actualFile, module)
			}

			v.modules = append(v.modules, module)
		}
	})

	// Check for cyclic dependencies (in modules)
	log.Timed("cyclic dependency check", "", func() {
		errs := v.depGraph.DetectCycles()
		if len(errs) > 0 {
			log.Error("main", "%s: Encountered cyclic dependency between: ", util.Bold(util.Red("error")))
			for _, cycle := range errs {
				log.Error("main", "%s", cycle)
			}
			log.Errorln("main", "")
			os.Exit(util.EXIT_FAILURE_SETUP)
		}
	})

	// construction
	log.Timed("construction phase", "", func() {
		for _, module := range v.modules {
			ast.Construct(module, v.moduleLookup)
		}
	})
}