check.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. package checker
  2. import (
  3. . "kumachan/error"
  4. "kumachan/loader"
  5. "kumachan/transformer/node"
  6. )
  7. type CheckedModule struct {
  8. Name string
  9. RawModule *loader.Module
  10. Imported map[string] *CheckedModule
  11. ConstantValues map[string] ExprLike
  12. FunctionBodies map[string] []ExprLike
  13. EffectsToBeDone [] Expr
  14. }
  15. type ExprLike interface { ExprLike() }
  16. func (impl ExprNative) ExprLike() {}
  17. type ExprNative string
  18. func (impl ExprExpr) ExprLike() {}
  19. type ExprExpr Expr
  20. type Index map[string] *CheckedModule
  21. type CheckContext struct {
  22. Types TypeRegistry
  23. Functions FunctionStore
  24. Constants ConstantStore
  25. }
  26. type ModuleInfo struct {
  27. Module *loader.Module
  28. Types TypeRegistry
  29. Constants ConstantCollection
  30. Functions FunctionCollection
  31. }
  32. type ExprContext struct {
  33. ModuleInfo ModuleInfo
  34. TypeParams [] string
  35. LocalValues map[string] Type
  36. InferTypeArgs bool
  37. InferredNames [] string
  38. Inferred map[uint] Type // mutable
  39. UnboxCounted bool
  40. UnboxCount *uint
  41. }
  42. type Expr struct {
  43. Type Type
  44. Value ExprVal
  45. Info ExprInfo
  46. }
  47. type ExprInfo struct {
  48. ErrorPoint ErrorPoint
  49. }
  50. type ExprVal interface { ExprVal() }
  51. type SemiExpr struct {
  52. Value SemiExprVal
  53. Info ExprInfo
  54. }
  55. type SemiExprVal interface { SemiExprVal() }
  56. func (impl TypedExpr) SemiExprVal() {}
  57. type TypedExpr Expr
  58. func LiftTyped(expr Expr) SemiExpr {
  59. return SemiExpr {
  60. Info: expr.Info,
  61. Value: TypedExpr(expr),
  62. }
  63. }
  64. type Sym interface { Sym() }
  65. func (impl SymLocalValue) Sym() {}
  66. type SymLocalValue struct { ValueType Type }
  67. func (impl SymConst) Sym() {}
  68. type SymConst struct { Const *Constant }
  69. func (impl SymTypeParam) Sym() {}
  70. type SymTypeParam struct { Index uint }
  71. func (impl SymType) Sym() {}
  72. type SymType struct { Type *GenericType }
  73. func (impl SymFunctions) Sym() {}
  74. type SymFunctions struct { Functions []*GenericFunction }
  75. func CreateExprContext(mod_info ModuleInfo, params []string) ExprContext {
  76. return ExprContext {
  77. ModuleInfo: mod_info,
  78. TypeParams: params,
  79. LocalValues: make(map[string]Type),
  80. InferTypeArgs: false,
  81. UnboxCounted: false,
  82. }
  83. }
  84. func (ctx ExprContext) GetTypeContext() TypeContext {
  85. return TypeContext {
  86. Module: ctx.ModuleInfo.Module,
  87. Params: ctx.TypeParams,
  88. Ireg: ctx.ModuleInfo.Types,
  89. }
  90. }
  91. func (ctx ExprContext) DescribeType(t Type) string {
  92. return DescribeTypeWithParams(t, ctx.TypeParams)
  93. }
  94. func (ctx ExprContext) DescribeExpectedType(t Type) string {
  95. if ctx.InferTypeArgs {
  96. return DescribeType(t, TypeDescContext {
  97. ParamNames: ctx.TypeParams,
  98. UseInferred: ctx.InferTypeArgs,
  99. InferredNames: ctx.InferredNames,
  100. InferredTypes: ctx.Inferred,
  101. })
  102. } else {
  103. return ctx.DescribeType(t)
  104. }
  105. }
  106. func (ctx ExprContext) GetModuleName() string {
  107. return loader.Id2String(ctx.ModuleInfo.Module.Node.Name)
  108. }
  109. func (ctx ExprContext) LookupSymbol(raw loader.Symbol) (Sym, bool) {
  110. var mod_name = raw.ModuleName
  111. var sym_name = raw.SymbolName
  112. if mod_name == "" {
  113. var t, exists = ctx.LocalValues[sym_name]
  114. if exists {
  115. return SymLocalValue { ValueType: t }, true
  116. }
  117. for index, param_name := range ctx.TypeParams {
  118. if param_name == sym_name {
  119. return SymTypeParam { Index: uint(index) }, true
  120. }
  121. }
  122. f_refs, exists := ctx.ModuleInfo.Functions[sym_name]
  123. if exists {
  124. var functions = make([]*GenericFunction, len(f_refs))
  125. for i, ref := range f_refs {
  126. functions[i] = ref.Function
  127. }
  128. return SymFunctions { Functions: functions }, true
  129. }
  130. var self = ctx.ModuleInfo.Module.Name
  131. var sym_self = loader.NewSymbol(self, sym_name)
  132. g, exists := ctx.ModuleInfo.Types[sym_self]
  133. if exists {
  134. return SymType { Type: g }, true
  135. }
  136. constant, exists := ctx.ModuleInfo.Constants[sym_self]
  137. if exists {
  138. return SymConst { Const: constant }, true
  139. }
  140. return nil, false
  141. } else {
  142. var g, exists = ctx.ModuleInfo.Types[raw]
  143. if exists {
  144. return SymType { Type: g }, true
  145. }
  146. constant, exists := ctx.ModuleInfo.Constants[raw]
  147. if exists {
  148. return SymConst { Const: constant }, true
  149. }
  150. return nil, false
  151. }
  152. }
  153. func (ctx ExprContext) WithAddedLocalValues(added map[string]Type) (ExprContext, string) {
  154. var merged = make(map[string]Type)
  155. for name, t := range ctx.LocalValues {
  156. var _, exists = added[name]
  157. if exists {
  158. return ExprContext{}, name
  159. }
  160. merged[name] = t
  161. }
  162. for name, t := range added {
  163. merged[name] = t
  164. }
  165. var new_ctx ExprContext
  166. *(&new_ctx) = ctx
  167. new_ctx.LocalValues = merged
  168. return new_ctx, ""
  169. }
  170. func (ctx ExprContext) WithTypeArgsInferringEnabled(names []string) ExprContext {
  171. var new_ctx ExprContext
  172. *(&new_ctx) = ctx
  173. new_ctx.InferTypeArgs = true
  174. new_ctx.InferredNames = names
  175. new_ctx.Inferred = make(map[uint] Type)
  176. return new_ctx
  177. }
  178. func (ctx ExprContext) WithUnboxCounted(count *uint) ExprContext {
  179. var new_ctx ExprContext
  180. *(&new_ctx) = ctx
  181. new_ctx.UnboxCounted = true
  182. new_ctx.UnboxCount = count
  183. *count = 0
  184. return new_ctx
  185. }
  186. func (ctx ExprContext) GetErrorPoint(node node.Node) ErrorPoint {
  187. return ErrorPoint {
  188. AST: ctx.ModuleInfo.Module.AST,
  189. Node: node,
  190. }
  191. }
  192. func (ctx ExprContext) GetExprInfo(node node.Node) ExprInfo {
  193. return ExprInfo { ErrorPoint: ctx.GetErrorPoint(node) }
  194. }
  195. func Check(expr node.Expr, ctx ExprContext) (SemiExpr, *ExprError) {
  196. return CheckCall(DesugarExpr(expr), ctx)
  197. }
  198. func CheckTerm(term node.VariousTerm, ctx ExprContext) (SemiExpr, *ExprError) {
  199. switch t := term.Term.(type) {
  200. case node.Cast:
  201. return CheckCast(t, ctx)
  202. case node.Lambda:
  203. return CheckLambda(t, ctx)
  204. case node.Switch:
  205. return CheckSwitch(t, ctx)
  206. case node.If:
  207. return CheckIf(t, ctx)
  208. case node.Block:
  209. return CheckBlock(t, ctx)
  210. case node.Tuple:
  211. return CheckTuple(t, ctx)
  212. case node.Bundle:
  213. return CheckBundle(t, ctx)
  214. case node.Get:
  215. return CheckGet(t, ctx)
  216. case node.Array:
  217. return CheckArray(t, ctx)
  218. case node.Text:
  219. return CheckText(t, ctx)
  220. case node.VariousLiteral:
  221. switch l := t.Literal.(type) {
  222. case node.IntegerLiteral:
  223. return CheckInteger(l, ctx)
  224. case node.FloatLiteral:
  225. return CheckFloat(l, ctx)
  226. case node.StringLiteral:
  227. return CheckString(l, ctx)
  228. default:
  229. panic("impossible branch")
  230. }
  231. case node.Ref:
  232. return CheckRef(t, ctx)
  233. case node.Infix:
  234. return CheckInfix(t, ctx)
  235. default:
  236. panic("impossible branch")
  237. }
  238. }
  239. func TypeCheck(entry *loader.Module, raw_index loader.Index) (
  240. *CheckedModule, Index, []E,
  241. ) {
  242. var types, err1 = RegisterTypes(entry, raw_index)
  243. if err1 != nil { return nil, nil, []E { err1 } }
  244. var constants = make(ConstantStore)
  245. var _, err2 = CollectConstants(entry, types, constants)
  246. if err2 != nil { return nil, nil, []E { err2 } }
  247. var functions = make(FunctionStore)
  248. var _, err3 = CollectFunctions(entry, types, functions)
  249. if err3 != nil { return nil, nil, []E { err3 } }
  250. var ctx = CheckContext {
  251. Types: types,
  252. Functions: functions,
  253. Constants: constants,
  254. }
  255. var checked_index = make(Index)
  256. var checked, errs = TypeCheckModule(entry, checked_index, ctx)
  257. if errs != nil { return nil, nil, errs }
  258. return checked, checked_index, nil
  259. }
  260. func TypeCheckModule(mod *loader.Module, index Index, ctx CheckContext) (
  261. *CheckedModule, []E,
  262. ) {
  263. var mod_name = mod.Name
  264. var existing, exists = index[mod_name]
  265. if exists {
  266. return existing, nil
  267. }
  268. var functions = ctx.Functions[mod_name]
  269. var constants = ctx.Constants[mod_name]
  270. var mod_info = ModuleInfo {
  271. Module: mod,
  272. Types: ctx.Types,
  273. Constants: constants,
  274. Functions: functions,
  275. }
  276. var errors = make([]E, 0)
  277. var imported = make(map[string]*CheckedModule)
  278. for alias, imported_item := range mod.ImpMap {
  279. var checked, errs = TypeCheckModule(imported_item, index, ctx)
  280. if errs != nil {
  281. errors = append(errors, errs...)
  282. continue
  283. }
  284. imported[alias] = checked
  285. }
  286. var func_map = make(map[string][]ExprLike)
  287. for name, group := range functions {
  288. func_map[name] = make([]ExprLike, 0)
  289. var add = func(b ExprLike) {
  290. func_map[name] = append(func_map[name], b)
  291. }
  292. for _, f_ref := range group {
  293. if f_ref.IsImported {
  294. continue
  295. }
  296. var f = f_ref.Function
  297. switch body := f.Body.(type) {
  298. case node.Lambda:
  299. var f_expr_ctx = CreateExprContext(mod_info, f.TypeParams)
  300. var lambda, err1 = CheckLambda(body, f_expr_ctx)
  301. if err1 != nil {
  302. errors = append(errors, err1)
  303. continue
  304. }
  305. var t = AnonymousType{f.DeclaredType}
  306. var body_expr, err2 = AssignTo(t, lambda, f_expr_ctx)
  307. if err2 != nil {
  308. errors = append(errors, err2)
  309. continue
  310. }
  311. add(ExprExpr(body_expr))
  312. case node.NativeRef:
  313. add(ExprNative(string(body.Id.Value)))
  314. default:
  315. panic("impossible branch")
  316. }
  317. }
  318. }
  319. var expr_ctx = CreateExprContext(mod_info, make([]string, 0))
  320. var const_map = make(map[string]ExprLike)
  321. for sym, constant := range constants {
  322. var name = sym.SymbolName
  323. switch val := constant.Value.(type) {
  324. case node.Expr:
  325. var semi_expr, err1 = Check(val, expr_ctx)
  326. if err1 != nil {
  327. errors = append(errors, err1)
  328. continue
  329. }
  330. var t = constant.DeclaredType
  331. var expr, err2 = AssignTo(t, semi_expr, expr_ctx)
  332. if err2 != nil {
  333. errors = append(errors, err2)
  334. continue
  335. }
  336. const_map[name] = ExprExpr(expr)
  337. case node.NativeRef:
  338. const_map[name] = ExprNative(string(val.Id.Value))
  339. default:
  340. panic("impossible branch")
  341. }
  342. }
  343. var do_effects = make([]Expr, 0)
  344. for _, cmd := range mod.Node.Commands {
  345. switch do := cmd.Command.(type) {
  346. case node.Do:
  347. var semi_expr, err1 = Check(do.Effect, expr_ctx)
  348. if err1 != nil {
  349. errors = append(errors, err1)
  350. continue
  351. }
  352. var expr, err2 = AssignTo(__DoType, semi_expr, expr_ctx)
  353. if err2 != nil {
  354. errors = append(errors, err2)
  355. continue
  356. }
  357. do_effects = append(do_effects, expr)
  358. }
  359. }
  360. if len(errors) > 0 {
  361. return nil, errors
  362. } else {
  363. var checked = &CheckedModule{
  364. Name: mod_name,
  365. RawModule: mod,
  366. Imported: imported,
  367. ConstantValues: const_map,
  368. FunctionBodies: func_map,
  369. EffectsToBeDone: do_effects,
  370. }
  371. index[mod_name] = checked
  372. return checked, nil
  373. }
  374. }