initial stage...
[yu.git] / yu / yu.lua
blob6c9538617adf3653e830aa2d99fd7880eb49a0ab
1 require "yu.parser"
2 require "yu.visitor"
3 require "yu.decl"
4 require "yu.resolver"
5 require "yu.codegen"
7 module("yu",package.seeall)
9 local builder={}
11 local function fixpath(p)
12 p=string.gsub(p,'\\','/')
13 return p
14 end
16 local function extractDir(p)
17 p=fixpath(p)
18 return string.match(p, ".*/")
19 end
21 local function extractFileName(p)
22 p=fixpath(p)
23 return string.match(p, "[%w_.%%]+$")
24 end
26 local function extractModName(p)
27 p=extractFileName(p)
28 p=string.gsub(p,'%.lx$','')
29 return string.gsub(p,'%.','_')
30 end
33 function newBuilder(option)
34 return setmetatable({
35 option=option,
36 moduleTable={},
37 buildingModules={}
38 },{__index=builder})
39 end
41 function builder:build(path)
42 self.baseDir=extractDir(path)
43 local m=self:requireModule(path)
44 for i,mm in ipairs(self.buildingModules) do
45 local res=yu.newResolver()
46 -- print('---------resolving module:',mm.path)
47 res:visitNode(mm)
48 end
49 return m
50 end
52 function builder:getAbsPath(path)
54 end
56 function builder:buildModule(path)
57 local m=parseFile(path)
58 m.externModules={}
59 m.path=path
60 m.name=extractModName(path)
61 self.moduleTable[path]=m
63 local heads=m.heads
64 local currentBase=extractDir(path)
65 -- print('---------collecting module:',path)
66 if heads then
67 for i,node in ipairs(heads) do
68 local tag=node.tag
69 if tag=='import' then
70 local modpath=currentBase..node.src
71 local requiredModule=self:requireModule(modpath)
72 if m==requiredModule then
73 --todo:error 'import self'
74 yu.compileErr('attempt to import self',node,m)
75 end
76 m.externModules[requiredModule.path]=requiredModule
77 node.mod=requiredModule
78 end
79 end
80 end
82 yu.newDeclCollector():visitNode(m)
83 -- yu.newResolver():visitNode(m)
84 self:addBuildingModule(m)
85 return m
86 end
88 function builder:addBuildingModule(m)
89 local b=self.buildingModules
90 for i,v in ipairs(b) do
91 if v==m then return end
92 end
93 b[#b+1]=m
94 end
96 function builder:requireModule(path)
97 path=fixpath(path)
98 --todo:unify path format
99 local m=self.moduleTable[path]
100 if not m then
101 --todo:search for precompiled module first
102 m=self:buildModule(path)
104 return m