header.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. package compiler
  2. import (
  3. "strings"
  4. "kumachan/standalone/ctn"
  5. "kumachan/lang/source"
  6. "kumachan/lang/typsys"
  7. "kumachan/lang/textual/ast"
  8. "kumachan/interpreter/program"
  9. )
  10. type NsHeaderMap struct { Map ctn.Map[string,*Header] }
  11. func groupHeaders(list ([] *Header), errs *source.Errors) *NsHeaderMap {
  12. var m0 = ctn.MakeMutMap[string,*([]*Header)](ctn.StringCompare)
  13. var m1 = ctn.MakeMutMap[string,*Header](ctn.StringCompare)
  14. for _, hdr := range list {
  15. var ns = hdr.namespace
  16. var existing, exists = m0.Lookup(ns)
  17. if !(exists) {
  18. var ptr = new([] *Header)
  19. m0.Insert(ns, ptr)
  20. existing = ptr
  21. }
  22. *existing = append(*existing, hdr)
  23. }
  24. m0.ForEach(func(ns string, ptr *([]*Header)) {
  25. m1.Insert(ns, mergeNsHeaders(ns, *ptr, errs))
  26. })
  27. return &NsHeaderMap { Map: m1.Map() }
  28. }
  29. func mergeNsHeaders(ns string, list ([] *Header), errs *source.Errors) *Header {
  30. var all_als_ns = ctn.MakeMutMap[string,*aliasTarget[string]](ctn.StringCompare)
  31. var all_als_ref = ctn.MakeMutMap[string,*aliasTarget[source.Ref]](ctn.StringCompare)
  32. var all_types = ctn.MakeMutMap[string,*typsys.TypeDef](ctn.StringCompare)
  33. var all_user = ctn.MakeMutMap[string,ctn.Map[string,*funHeader]](ctn.StringCompare)
  34. var all_gen = ctn.MakeMutMap[genFunKey,*funHeader](genFunKeyCompare)
  35. for _, hdr := range list {
  36. if hdr.namespace != ns {
  37. panic("invalid arguments")
  38. }
  39. hdr.nsAliasMap.ForEach(func(name string, item *aliasTarget[string]) {
  40. var _, duplicate = all_als_ns.Lookup(name)
  41. if duplicate {
  42. var loc = item.Location
  43. source.ErrorsJoin(errs, source.MakeError(loc,
  44. E_DuplicateAlias { Name: name }))
  45. } else {
  46. all_als_ns.Insert(name, item)
  47. }
  48. })
  49. hdr.refAliasMap.ForEach(func(name string, item *aliasTarget[source.Ref]) {
  50. var _, duplicate = all_als_ref.Lookup(name)
  51. if duplicate {
  52. var loc = item.Location
  53. source.ErrorsJoin(errs, source.MakeError(loc,
  54. E_DuplicateAlias { Name: name }))
  55. } else {
  56. all_als_ref.Insert(name, item)
  57. }
  58. })
  59. hdr.typeMap.ForEach(func(name string, item *typsys.TypeDef) {
  60. var _, duplicate = all_types.Lookup(name)
  61. if duplicate {
  62. var loc = item.Info.Location
  63. source.ErrorsJoin(errs, source.MakeError(loc,
  64. E_DuplicateTypeDecl { Name: name }))
  65. } else {
  66. all_types.Insert(name, item)
  67. }
  68. })
  69. hdr.userFunMap.ForEach(func(name string, items ctn.Map[string,*funHeader]) {
  70. var group = (func() ctn.Map[string, *funHeader] {
  71. var group, exists = all_user.Lookup(name)
  72. if exists {
  73. return group
  74. } else {
  75. return ctn.MakeMap[string,*funHeader](ctn.StringCompare)
  76. }
  77. })()
  78. items.ForEach(func(assoc string, item *funHeader) {
  79. var duplicate = group.Has(assoc)
  80. if duplicate {
  81. var loc = item.funInfo.Location
  82. source.ErrorsJoin(errs, source.MakeError(loc,
  83. E_DuplicateFunDecl { Name: name, Assoc: assoc }))
  84. } else {
  85. group = group.Inserted(assoc, item)
  86. }
  87. })
  88. all_user.Insert(name, group)
  89. })
  90. hdr.genFunMap.ForEach(func(key genFunKey, item *funHeader) {
  91. all_gen.Insert(key, item)
  92. })
  93. }
  94. return &Header {
  95. namespace: ns,
  96. nsAliasMap: all_als_ns.Map(),
  97. refAliasMap: all_als_ref.Map(),
  98. typeMap: all_types.Map(),
  99. userFunMap: all_user.Map(),
  100. genFunMap: all_gen.Map(),
  101. }
  102. }
  103. func (ctx *NsHeaderMap) FindType(ref source.Ref) (*typsys.TypeDef, bool) {
  104. return ctx.lookupType(ref)
  105. }
  106. func (ctx *NsHeaderMap) generateTypeInfo() program.TypeInfo {
  107. var reg = make(map[source.Ref] *typsys.TypeDef)
  108. ctx.Map.ForEach(func(ns string, hdr *Header) {
  109. hdr.typeMap.ForEach(func(name string, def *typsys.TypeDef) {
  110. var ref = source.MakeRef(ns, name)
  111. reg[ref] = def
  112. })
  113. })
  114. return program.TypeInfo {
  115. TypeRegistry: reg,
  116. }
  117. }
  118. func (ctx* NsHeaderMap) tryRedirectRef(ns string, ref *source.Ref) bool {
  119. if hdr, ok := ctx.Map.Lookup(ns); ok {
  120. if target, ok := hdr.nsAliasMap.Lookup(ref.Namespace); ok {
  121. if target.Valid {
  122. *ref = source.MakeRef(target.Target, ref.ItemName)
  123. return true
  124. }}
  125. if ref.Namespace == "" {
  126. if target, ok := hdr.refAliasMap.Lookup(ref.ItemName); ok {
  127. if target.Valid {
  128. *ref = target.Target
  129. return true
  130. }}
  131. }
  132. }
  133. if ns != "" {
  134. if ref.Namespace == "" {
  135. *ref = source.MakeRef(ns, ref.ItemName)
  136. return true
  137. }
  138. }
  139. return false
  140. }
  141. func (ctx *NsHeaderMap) lookupType(ref source.Ref) (*typsys.TypeDef, bool) {
  142. if hdr, ok := ctx.Map.Lookup(ref.Namespace); ok {
  143. if def, ok := hdr.typeMap.Lookup(ref.ItemName); ok {
  144. return def, true
  145. }}
  146. return nil, false
  147. }
  148. func (ctx *NsHeaderMap) lookupMethod(recv_ref source.Ref, name string) (*funHeader, bool) {
  149. if hdr, ok := ctx.Map.Lookup(recv_ref.Namespace); ok {
  150. if group, ok := hdr.userFunMap.Lookup(name); ok {
  151. if f, ok := group.Lookup(recv_ref.ItemName); ok {
  152. if f.funKind == FK_Method {
  153. return f, true
  154. }
  155. }}}
  156. return nil, false
  157. }
  158. func (ctx *NsHeaderMap) lookupExactFunction(ref source.Ref, assoc string, kind FunKind) (*funHeader, string, userFunKey, bool) {
  159. if hdr, ok := ctx.Map.Lookup(ref.Namespace); ok {
  160. if group, ok := hdr.userFunMap.Lookup(ref.ItemName); ok {
  161. if f, ok := group.Lookup(assoc); ok {
  162. if f.funKind == kind {
  163. var ns = ref.Namespace
  164. var key = userFunKey {
  165. name: ref.ItemName,
  166. assoc: assoc,
  167. }
  168. return f, ns, key, true
  169. }
  170. }}}
  171. return nil, "", userFunKey{}, false
  172. }
  173. func (ctx *NsHeaderMap) lookupFunction(ref source.Ref, r0 ctn.Optional[source.Ref], kind FunKind) (*funHeader, string, userFunKey, bool) {
  174. if r0, ok := r0.Value(); ok {
  175. var ns, item = ref.Namespace, ref.ItemName
  176. var NS, A = r0.Namespace, r0.ItemName
  177. if ((NS != "") && (ns == "")) {
  178. if f, ns, key, ok := ctx.lookupExactFunction(ref, "", kind); ok {
  179. return f, ns, key, true
  180. }
  181. return ctx.lookupExactFunction(source.MakeRef(NS, item), A, kind)
  182. }
  183. if (NS == ns) {
  184. if f, ns, key, ok := ctx.lookupExactFunction(ref, A, kind); ok {
  185. return f, ns, key, true
  186. }
  187. return ctx.lookupExactFunction(ref, "", kind)
  188. }
  189. }
  190. return ctx.lookupExactFunction(ref, "", kind)
  191. }
  192. func (ctx *NsHeaderMap) lookupReferableFunctions(ref source.Ref) ([] func()(*funHeader,string,userFunKey)) {
  193. var ns = ref.Namespace
  194. var name = ref.ItemName
  195. var list = make([] func()(*funHeader,string,userFunKey), 0)
  196. if hdr, ok := ctx.Map.Lookup(ns); ok {
  197. if group, ok := hdr.userFunMap.Lookup(name); ok {
  198. group.ForEach(func(assoc string, f *funHeader) {
  199. if isReferable(f) {
  200. list = append(list, func() (*funHeader, string, userFunKey) {
  201. var key = userFunKey { name: name, assoc: assoc }
  202. return f, ns, key
  203. })
  204. }
  205. })
  206. }}
  207. return list
  208. }
  209. type Header struct {
  210. namespace string
  211. nsAliasMap ctn.Map[string, *aliasTarget[string]]
  212. refAliasMap ctn.Map[string, *aliasTarget[source.Ref]]
  213. typeMap ctn.Map[string, *typsys.TypeDef]
  214. userFunMap ctn.Map[string, ctn.Map[string, *funHeader]]
  215. genFunMap ctn.Map[genFunKey, *funHeader]
  216. }
  217. type aliasTarget[T any] struct {
  218. Valid bool
  219. Target T
  220. Location source.Location
  221. }
  222. type funHeader struct {
  223. funKind FunKind
  224. funInfo FunInfo
  225. variadic bool
  226. typeParams [] string
  227. output funOutput
  228. inputsExplicit *typsys.Fields
  229. inputsImplicit *typsys.Fields
  230. }
  231. type funOutput struct {
  232. type_ typsys.Type
  233. loc source.Location
  234. }
  235. type FunKind int
  236. const (
  237. FK_Generated FunKind = iota
  238. FK_Ordinary
  239. FK_Operator
  240. FK_Method
  241. FK_Const
  242. FK_Entry
  243. )
  244. type FunInfo struct {
  245. Location source.Location
  246. Document string
  247. }
  248. func isReferable(f *funHeader) bool {
  249. switch f.funKind {
  250. case FK_Ordinary, FK_Operator, FK_Const:
  251. if len(f.inputsImplicit.FieldList) == 0 {
  252. return true
  253. }}
  254. return false
  255. }
  256. func someReferable(group ctn.Map[string,*funHeader]) bool {
  257. var result = false
  258. group.ForEach(func(_ string, f *funHeader) {
  259. result = (result || isReferable(f))
  260. })
  261. return result
  262. }
  263. type genFunKey struct {
  264. typeName string
  265. funName string
  266. fieldName string
  267. }
  268. func (key genFunKey) Describe(ns string) string {
  269. var elements = [] string { ns, key.typeName, key.funName, key.fieldName }
  270. var buf strings.Builder
  271. buf.WriteRune('[')
  272. buf.WriteString(strings.Join(elements, ","))
  273. buf.WriteRune(']')
  274. return buf.String()
  275. }
  276. func genFunKeyCompare(a genFunKey, b genFunKey) ctn.Ordering {
  277. var o = ctn.StringCompare(a.typeName, b.typeName)
  278. if o != ctn.Equal {
  279. return o
  280. } else {
  281. var o = ctn.StringCompare(a.funName, b.funName)
  282. if o != ctn.Equal {
  283. return o
  284. } else {
  285. return ctn.StringCompare(a.fieldName, b.fieldName)
  286. }
  287. }
  288. }
  289. func analyze(root *ast.Root, errs *source.Errors) (*Header,*Impl) {
  290. var ns = ast.MaybeId2String(root.Namespace)
  291. var als_ns = ctn.MakeMutMap[string,*aliasTarget[string]](ctn.StringCompare)
  292. var als_ref = ctn.MakeMutMap[string,*aliasTarget[source.Ref]](ctn.StringCompare)
  293. var types = ctn.MakeMutMap[string,*typsys.TypeDef](ctn.StringCompare)
  294. var types_gen = ctn.MakeMutMap[string,generatedConstList](ctn.StringCompare)
  295. var user_hdr = ctn.MakeMutMap[string,ctn.Map[string,*funHeader]](ctn.StringCompare)
  296. var user_impl = ctn.MakeMutMap[userFunKey,funImpl](userFunKeyCompare)
  297. var user_gen = ctn.MakeMutMap[userFunKey,generatedConstList](userFunKeyCompare)
  298. var gen_hdr = ctn.MakeMutMap[genFunKey,*funHeader](genFunKeyCompare)
  299. var gen_impl = ctn.MakeMutMap[genFunKey,funImpl](genFunKeyCompare)
  300. for _, alias := range root.Aliases {
  301. if alias.Off {
  302. continue
  303. }
  304. var loc = alias.Location
  305. switch T := alias.Target.AliasTarget.(type) {
  306. case ast.AliasToNamespace:
  307. var target = ast.Id2String(T.Namespace)
  308. var name = ast.MaybeId2String(alias.Name)
  309. var duplicate = als_ns.Has(name)
  310. if duplicate {
  311. source.ErrorsJoin(errs, source.MakeError(loc,
  312. E_DuplicateAlias {
  313. Name: name,
  314. }))
  315. continue
  316. }
  317. als_ns.Insert(name, &aliasTarget[string] {
  318. Valid: true,
  319. Target: target,
  320. Location: loc,
  321. })
  322. case ast.AliasToRefBase:
  323. var target = getRef(T.RefBase)
  324. var name = (func() string {
  325. if name := ast.MaybeId2String(alias.Name); name != "" {
  326. return name
  327. } else {
  328. return target.ItemName
  329. }
  330. })()
  331. var duplicate = als_ref.Has(name)
  332. if duplicate {
  333. source.ErrorsJoin(errs, source.MakeError(loc,
  334. E_DuplicateAlias {
  335. Name: name,
  336. }))
  337. continue
  338. }
  339. als_ref.Insert(name, &aliasTarget[source.Ref] {
  340. Valid: true,
  341. Target: target,
  342. Location: loc,
  343. })
  344. default:
  345. panic("impossible branch")
  346. }
  347. }
  348. var pm = makeParamMapping(root.Statements)
  349. for _, stmt := range root.Statements {
  350. switch S := stmt.Statement.(type) {
  351. case ast.DeclType:
  352. if S.Off {
  353. continue
  354. }
  355. var name = ast.Id2String(S.Name)
  356. if types.Has(name) {
  357. source.ErrorsJoin(errs, source.MakeError(S.Location,
  358. E_DuplicateTypeDecl {
  359. Name: name,
  360. }))
  361. continue
  362. }
  363. var loc = S.Location
  364. var doc = ast.GetDocContent(S.Docs)
  365. var info = typsys.Info { Location: loc, Document: doc }
  366. var ref = source.MakeRef(ns, name)
  367. var ifs = ctn.MapEach(S.Implements, getRef)
  368. var params = ctn.MapEach(S.TypeParams, ast.Id2String)
  369. var ctx = createTypeConsContext(params)
  370. var gen = make(generatedConstList, 0)
  371. var content = makeTypeDefContent(S.TypeDef, ctx, &gen, errs)
  372. types_gen.Insert(name, gen)
  373. types.Insert(name, &typsys.TypeDef {
  374. Info: info,
  375. Ref: ref,
  376. Interfaces: ifs,
  377. Parameters: params,
  378. Content: content,
  379. })
  380. default:
  381. var u = unifyFunDecl(S, pm, ns)
  382. if u.off {
  383. continue
  384. }
  385. var name = ast.Id2String(u.name)
  386. var group = (func() ctn.Map[string, *funHeader] {
  387. var group, exists = user_hdr.Lookup(name)
  388. if exists {
  389. return group
  390. } else {
  391. return ctn.MakeMap[string,*funHeader](ctn.StringCompare)
  392. }
  393. })()
  394. var params = ctn.MapEach(u.sig.TypeParams, ast.Id2String)
  395. var ctx = createTypeConsContext(params)
  396. var kind = u.kind
  397. var assoc = getAssocTypeName(u.sig.Inputs, kind, ns, ctx)
  398. var duplicate = group.Has(assoc)
  399. if duplicate {
  400. source.ErrorsJoin(errs, source.MakeError(u.loc,
  401. E_DuplicateFunDecl {
  402. Name: name,
  403. Assoc: assoc,
  404. }))
  405. continue
  406. }
  407. var key = userFunKey { name: name, assoc: assoc }
  408. var impl = u.impl
  409. var loc = u.loc
  410. var doc = ast.GetDocContent(u.doc)
  411. var info = FunInfo { Location: loc, Document: doc }
  412. var va = u.va
  413. var gen = make(generatedConstList, 0)
  414. var in_exp_ = u.sig.Inputs
  415. var in_imp_ = u.sig.Implicit
  416. var in_exp = makeFunInputFields(in_exp_, nil, ctx, &gen, errs)
  417. var in_imp = makeFunInputFields(in_imp_, in_exp, ctx, &gen, errs)
  418. var out_t = makeType(u.sig.Output, ctx)
  419. var out = funOutput { type_: out_t, loc: u.sig.Output.Location }
  420. user_gen.Insert(key, gen)
  421. user_hdr.Insert(name, group.Inserted(assoc, &funHeader {
  422. funKind: kind,
  423. funInfo: info,
  424. variadic: va,
  425. typeParams: params,
  426. output: out,
  427. inputsExplicit: in_exp,
  428. inputsImplicit: in_imp,
  429. }))
  430. user_impl.Insert(key, impl)
  431. }
  432. }
  433. types_gen.ForEach(func(src_type_name string, list generatedConstList) {
  434. var params = (func() ([] string) {
  435. var src_type_def, ok = types.Lookup(src_type_name)
  436. if !(ok) { panic("something went wrong") }
  437. return src_type_def.Parameters
  438. })()
  439. list.consume(params, func(item_name string, item_hdr *funHeader, item_impl funImpl) {
  440. var key = genFunKey {
  441. typeName: src_type_name,
  442. fieldName: item_name,
  443. }
  444. if gen_hdr.Has(key) { panic("something went wrong") }
  445. gen_hdr.Insert(key, item_hdr)
  446. gen_impl.Insert(key, item_impl)
  447. })
  448. })
  449. user_gen.ForEach(func(fun_key userFunKey, list generatedConstList) {
  450. var params = (func() ([] string) {
  451. var group = (func() ctn.Map[string, *funHeader] {
  452. var group, ok = user_hdr.Lookup(fun_key.name)
  453. if !(ok) { panic("something went wrong") }
  454. return group
  455. })()
  456. var f_hdr, ok = group.Lookup(fun_key.assoc)
  457. if !(ok) { panic("something went wrong") }
  458. return f_hdr.typeParams
  459. })()
  460. list.consume(params, func(item_name string, item_hdr *funHeader, item_impl funImpl) {
  461. var key = genFunKey {
  462. funName: fun_key.name,
  463. typeName: fun_key.assoc,
  464. fieldName: item_name,
  465. }
  466. if gen_hdr.Has(key) { panic("something went wrong") }
  467. gen_hdr.Insert(key, item_hdr)
  468. gen_impl.Insert(key, item_impl)
  469. })
  470. })
  471. var hdr = &Header {
  472. namespace: ns,
  473. nsAliasMap: als_ns.Map(),
  474. refAliasMap: als_ref.Map(),
  475. typeMap: types.Map(),
  476. userFunMap: user_hdr.Map(),
  477. genFunMap: gen_hdr.Map(),
  478. }
  479. var impl = &Impl {
  480. namespace: ns,
  481. userFunMap: user_impl.Map(),
  482. genFunMap: gen_impl.Map(),
  483. }
  484. return hdr, impl
  485. }
  486. type generatedConst struct {
  487. name string
  488. val funImpl
  489. typ typsys.Type
  490. loc source.Location
  491. doc string
  492. }
  493. type generatedConstList ([] generatedConst)
  494. func (list generatedConstList) consume(params ([] string), k func(string,*funHeader,funImpl)) {
  495. for _, item := range list {
  496. var info = FunInfo {
  497. Location: item.loc,
  498. Document: item.doc,
  499. }
  500. var out = funOutput {
  501. type_: item.typ,
  502. loc: item.loc,
  503. }
  504. var item_hdr = &funHeader {
  505. funKind: FK_Generated,
  506. funInfo: info,
  507. typeParams: params,
  508. output: out,
  509. inputsExplicit: &typsys.Fields {},
  510. inputsImplicit: &typsys.Fields {},
  511. }
  512. var item_impl = item.val
  513. k(item.name, item_hdr, item_impl)
  514. }
  515. }
  516. func checkHeader(hdr *Header, ctx *NsHeaderMap, errs *source.Errors) {
  517. validateAlterHeaderAliases(hdr, ctx, errs)
  518. validateAlterHeaderTypes(hdr, ctx, errs)
  519. validateHeaderFunctions(hdr, ctx, errs)
  520. }
  521. func validateAlterHeaderAliases(hdr *Header, ctx *NsHeaderMap, errs *source.Errors) {
  522. var hasRelevantRef = func(ref source.Ref) bool {
  523. if ref_hdr, ok := ctx.Map.Lookup(ref.Namespace); ok {
  524. if ref_hdr.typeMap.Has(ref.ItemName) {
  525. return true
  526. }
  527. if group, ok := ref_hdr.userFunMap.Lookup(ref.ItemName); ok {
  528. if someReferable(group) {
  529. return true
  530. }}
  531. }
  532. return false
  533. }
  534. var setInvalidAndThrow = func(valid *bool, err *source.Error) {
  535. *valid = false
  536. source.ErrorsJoin(errs, err)
  537. }
  538. hdr.nsAliasMap.ForEach(func(name string, target *aliasTarget[string]) {
  539. var v, loc = &(target.Valid), target.Location
  540. if ctx.Map.Has(name) {
  541. setInvalidAndThrow(v, source.MakeError(loc,
  542. E_InvalidAlias {
  543. Name: name,
  544. }))
  545. }
  546. if !(ctx.Map.Has(target.Target)) {
  547. setInvalidAndThrow(v, source.MakeError(loc,
  548. E_AliasTargetNotFound {
  549. Target: ("namespace " + target.Target),
  550. }))
  551. }
  552. })
  553. hdr.refAliasMap.ForEach(func(name string, target *aliasTarget[source.Ref]) {
  554. var v, loc = &(target.Valid), target.Location
  555. if hasRelevantRef(source.MakeRef("", name)) {
  556. setInvalidAndThrow(v, source.MakeError(loc,
  557. E_InvalidAlias {
  558. Name: name,
  559. }))
  560. }
  561. if !(hasRelevantRef(target.Target)) {
  562. setInvalidAndThrow(v, source.MakeError(loc,
  563. E_AliasTargetNotFound {
  564. Target: target.Target.String(),
  565. }))
  566. }
  567. })
  568. }
  569. func validateAlterHeaderTypes(hdr *Header, ctx *NsHeaderMap, errs *source.Errors) {
  570. var ns = hdr.namespace
  571. var validateAlterSingleType = func(t *typsys.Type, loc source.Location) {
  572. var err = validateAlterType(t, loc, ns, ctx)
  573. source.ErrorsJoin(errs, err)
  574. }
  575. var validateAlterFieldTypes = func(fields *typsys.Fields) {
  576. for i := range fields.FieldList {
  577. var field = &(fields.FieldList[i])
  578. if field.Type != nil {
  579. var loc = field.Info.Location
  580. var field_t = &(field.Type)
  581. validateAlterSingleType(field_t, loc)
  582. }
  583. }
  584. }
  585. hdr.typeMap.ForEach(func(_ string, def *typsys.TypeDef) {
  586. for i := range def.Interfaces {
  587. var ref = &(def.Interfaces[i])
  588. var loc = def.Info.Location
  589. var err = validateAlterInterfaceTypeRef(ref, loc, ns, ctx)
  590. source.ErrorsJoin(errs, err)
  591. }
  592. var fields, ok = (func() (*typsys.Fields, bool) {
  593. switch content := def.Content.(type) {
  594. case typsys.Record: return content.Fields, true
  595. case typsys.Union: return content.Fields, true
  596. case typsys.Interface: return content.Fields, true
  597. default: return nil, false
  598. }
  599. })()
  600. if ok {
  601. validateAlterFieldTypes(fields)
  602. }
  603. })
  604. hdr.userFunMap.ForEach(func(_ string, group ctn.Map[string,*funHeader]) {
  605. group.ForEach(func(_ string, f *funHeader) {
  606. validateAlterFieldTypes(f.inputsExplicit)
  607. validateAlterFieldTypes(f.inputsImplicit)
  608. validateAlterSingleType(&(f.output.type_), f.output.loc)
  609. })})
  610. hdr.genFunMap.ForEach(func(_ genFunKey, f *funHeader) {
  611. validateAlterFieldTypes(f.inputsExplicit)
  612. validateAlterFieldTypes(f.inputsImplicit)
  613. validateAlterSingleType(&(f.output.type_), f.output.loc)
  614. })
  615. }
  616. func validateAlterType(t *typsys.Type, loc source.Location, ns string, ctx *NsHeaderMap) *source.Error {
  617. var first_error *source.Error = nil
  618. var throw = func(err *source.Error) {
  619. if first_error == nil {
  620. first_error = err
  621. }
  622. }
  623. *t = typsys.Transform(*t, func(t typsys.Type) (typsys.Type, bool) {
  624. if ref_type, ok := t.(typsys.RefType); ok {
  625. var ref = ref_type.Def
  626. var def, exists = ctx.lookupType(ref)
  627. var ref_altered = false
  628. if !(exists) {
  629. if ctx.tryRedirectRef(ns, &ref) {
  630. ref_altered = true
  631. def, exists = ctx.lookupType(ref)
  632. }
  633. }
  634. if !(exists) {
  635. throw(source.MakeError(loc,
  636. E_NoSuchType {
  637. ref.String(),
  638. }))
  639. return program.T_InvalidType(), true
  640. }
  641. var required = len(def.Parameters)
  642. var given = len(ref_type.Args)
  643. if given != required {
  644. throw(source.MakeError(loc,
  645. E_TypeArgsWrongQuantity {
  646. Type: ref.String(),
  647. Given: given,
  648. Required: required,
  649. }))
  650. return program.T_InvalidType(), true
  651. }
  652. if ref_altered {
  653. return typsys.RefType {
  654. Def: ref,
  655. Args: ref_type.Args,
  656. }, true
  657. }
  658. }
  659. return nil, false
  660. })
  661. return first_error
  662. }
  663. func validateAlterInterfaceTypeRef(ref *source.Ref, loc source.Location, ns string, ctx *NsHeaderMap) *source.Error {
  664. // NOTE: this function requires T_InvalidType to be an interface type
  665. var def, exists = ctx.lookupType(*ref)
  666. if !(exists) {
  667. if ctx.tryRedirectRef(ns, ref) {
  668. def, exists = ctx.lookupType(*ref)
  669. }
  670. }
  671. if !(exists) {
  672. var err = source.MakeError(loc, E_NoSuchType { (*ref).String() })
  673. *ref = program.T_InvalidType().(typsys.RefType).Def
  674. return err
  675. }
  676. var _, ok = def.Content.(typsys.Interface)
  677. if !(ok) {
  678. var err = source.MakeError(loc, E_NotInterface { (*ref).String() })
  679. *ref = program.T_InvalidType().(typsys.RefType).Def
  680. return err
  681. }
  682. return nil
  683. }
  684. func validateHeaderFunctions(hdr *Header, ctx *NsHeaderMap, errs *source.Errors) {
  685. hdr.userFunMap.ForEach(func(name string, group ctn.Map[string,*funHeader]) {
  686. group.ForEach(func(assoc string, f *funHeader) {
  687. if f.funKind == FK_Method {
  688. var ns = hdr.namespace
  689. var type_ref = source.MakeRef(ns, assoc)
  690. if def, ok := ctx.lookupType(type_ref); ok {
  691. var conflict = (func() bool {
  692. if R, ok := def.Content.(typsys.Record); ok {
  693. var _, conflict = R.FieldIndexMap[name]
  694. return conflict
  695. }
  696. if I, ok := def.Content.(typsys.Interface); ok {
  697. var _, conflict = I.FieldIndexMap[name]
  698. return conflict
  699. }
  700. return false
  701. })()
  702. if conflict {
  703. var err = source.MakeError(f.funInfo.Location,
  704. E_MethodNameUnavailable {
  705. Name: name,
  706. })
  707. source.ErrorsJoin(errs, err)
  708. }
  709. }
  710. }
  711. if f.funKind == FK_Operator {
  712. var in_exp = f.inputsExplicit.FieldList
  713. if len(in_exp) == 0 {
  714. var loc = f.funInfo.Location
  715. source.ErrorsJoin(errs, source.MakeError(loc,
  716. E_MissingOperatorParameter {}))
  717. }
  718. }
  719. if f.variadic {
  720. var in_exp = f.inputsExplicit.FieldList
  721. var arity = len(in_exp)
  722. if arity == 0 {
  723. var loc = f.funInfo.Location
  724. source.ErrorsJoin(errs, source.MakeError(loc,
  725. E_MissingVariadicParameter {}))
  726. } else {
  727. var last_index = (arity - 1)
  728. var last = in_exp[last_index]
  729. if _, ok := program.T_List_(last.Type); ok {
  730. // OK
  731. } else {
  732. var loc = f.funInfo.Location
  733. source.ErrorsJoin(errs, source.MakeError(loc,
  734. E_InvalidVariadicParameter {}))
  735. }
  736. }
  737. }
  738. for _, imp_field := range f.inputsImplicit.FieldList {
  739. if P, _, ok := ast.SplitImplicitRef(imp_field.Name); ok {
  740. var ok = false
  741. for _, p := range f.typeParams {
  742. if p == P {
  743. ok = true
  744. break
  745. }
  746. }
  747. if !(ok) {
  748. var loc = imp_field.Info.Location
  749. source.ErrorsJoin(errs, source.MakeError(loc,
  750. E_NoSuchTypeParameter { P }))
  751. }
  752. }
  753. }
  754. })})
  755. }
  756. type typeConsContext struct {
  757. parameters map[string] struct{}
  758. }
  759. func createTypeConsContext(params ([] string)) *typeConsContext {
  760. return &typeConsContext {
  761. parameters: (func() (map[string] struct{}) {
  762. var set = make(map[string] struct{})
  763. for _, p := range params {
  764. set[p] = struct{}{}
  765. }
  766. return set
  767. })(),
  768. }
  769. }
  770. func (ctx *typeConsContext) hasTypeParameter() bool {
  771. return (len(ctx.parameters) > 0)
  772. }
  773. func (ctx *typeConsContext) isTypeParameter(name string) bool {
  774. var _, is_parameter = ctx.parameters[name]
  775. return is_parameter
  776. }
  777. func makeType(t ast.Type, ctx *typeConsContext) typsys.Type {
  778. var param_name, is_param = getTypeParamName(t.Ref.Base, ctx)
  779. if is_param {
  780. return typsys.ParameterType {
  781. Name: param_name,
  782. }
  783. } else {
  784. var def_ref = getRef(t.Ref.Base)
  785. var args = make([] typsys.Type, len(t.Ref.TypeArgs))
  786. for i := range t.Ref.TypeArgs {
  787. args[i] = makeType(t.Ref.TypeArgs[i], ctx)
  788. }
  789. return typsys.RefType {
  790. Def: def_ref,
  791. Args: args,
  792. }
  793. }
  794. }
  795. func makeTypeDefContent (
  796. content ast.VariousTypeDef,
  797. ctx *typeConsContext,
  798. gen *generatedConstList,
  799. errs *source.Errors,
  800. ) typsys.TypeDefContent {
  801. type fieldNode struct {
  802. loc source.Location
  803. doc [] ast.Doc
  804. name ast.Identifier
  805. type_ ctn.Optional[ast.Type]
  806. dv ast.MaybeExpr
  807. }
  808. var collect = func(kind string, nodes ([] fieldNode)) typsys.Fields {
  809. var fields = make([] typsys.Field, len(nodes))
  810. var index = make(map[string] int)
  811. for i, node := range nodes {
  812. var name = ast.Id2String(node.name)
  813. if !(isValidFieldName(name)) {
  814. source.ErrorsJoin(errs, source.MakeError(
  815. node.loc,
  816. E_InvalidFieldName {
  817. FieldKind: kind,
  818. FieldName: name,
  819. },
  820. ))
  821. continue
  822. }
  823. if _, duplicate := index[name]; duplicate {
  824. source.ErrorsJoin(errs, source.MakeError(
  825. node.loc,
  826. E_DuplicateField {
  827. FieldKind: kind,
  828. FieldName: name,
  829. },
  830. ))
  831. continue
  832. }
  833. var loc = node.loc
  834. var doc = ast.GetDocContent(node.doc)
  835. var type_ typsys.Type
  836. if type_node, ok := node.type_.Value(); ok {
  837. type_ = makeType(type_node, ctx)
  838. }
  839. var default_, has_default = node.dv.(ast.Expr)
  840. if has_default {
  841. *gen = append(*gen, generatedConst {
  842. name: name,
  843. val: funImplAstExpr { default_ },
  844. typ: type_,
  845. loc: default_.Location,
  846. doc: "",
  847. })
  848. }
  849. var info = typsys.FieldInfo {
  850. Info: typsys.Info { Location: loc, Document: doc },
  851. HasDefaultValue: has_default,
  852. }
  853. fields[i] = typsys.Field {
  854. Info: info,
  855. Name: name,
  856. Type: type_,
  857. }
  858. index[name] = i
  859. }
  860. return typsys.Fields {
  861. FieldIndexMap: index,
  862. FieldList: fields,
  863. }
  864. }
  865. switch C := content.TypeDef.(type) {
  866. case ast.Record:
  867. var nodes = ctn.MapEach(C.Def.Fields, func(raw ast.Field) fieldNode {
  868. return fieldNode {
  869. loc: raw.Location,
  870. doc: raw.Docs,
  871. name: raw.Name,
  872. type_: ctn.Just(raw.Type),
  873. dv: raw.Default,
  874. }
  875. })
  876. var fields = collect("field", nodes)
  877. return typsys.Record {
  878. Fields: &fields,
  879. }
  880. case ast.Interface:
  881. var nodes = ctn.MapEach(C.Methods, func(raw ast.Method) fieldNode {
  882. return fieldNode {
  883. loc: raw.Location,
  884. doc: raw.Docs,
  885. name: raw.Name,
  886. type_: ctn.Just(raw.Type),
  887. dv: nil,
  888. }
  889. })
  890. var methods = collect("method", nodes)
  891. return typsys.Interface {
  892. Fields: &methods,
  893. }
  894. case ast.Union:
  895. var nodes = make([] fieldNode, 0)
  896. for _, item := range C.Items {
  897. nodes = append(nodes, fieldNode {
  898. loc: item.Location,
  899. doc: nil,
  900. name: item.Ref.Base.Item,
  901. type_: ctn.Just(item),
  902. dv: nil,
  903. })
  904. }
  905. var items = collect("item", nodes)
  906. return typsys.Union {
  907. Fields: &items,
  908. }
  909. case ast.Enum:
  910. if ctx.hasTypeParameter() {
  911. source.ErrorsJoin(errs, source.MakeError(
  912. content.Location,
  913. E_GenericEnum {},
  914. ))
  915. }
  916. var nodes = make([] fieldNode, 0)
  917. for _, item := range C.Items {
  918. nodes = append(nodes, fieldNode {
  919. loc: item.Location,
  920. doc: item.Docs,
  921. name: item.Name,
  922. type_: nil,
  923. dv: nil,
  924. })
  925. }
  926. var items = collect("item", nodes)
  927. return typsys.Enum {
  928. Fields: &items,
  929. }
  930. case ast.NativeTypeDef:
  931. return typsys.NativeContent {}
  932. default:
  933. panic("impossible branch")
  934. }
  935. }
  936. func makeFunInputFields (
  937. inputs ast.MaybeInputs,
  938. saved *typsys.Fields,
  939. ctx *typeConsContext,
  940. gen *generatedConstList,
  941. errs *source.Errors,
  942. ) *typsys.Fields {
  943. if inputs, ok := inputs.(ast.Inputs); ok {
  944. var nodes = inputs.Content.Fields
  945. var fields = make([] typsys.Field, len(nodes))
  946. var index = make(map[string] int)
  947. for i, node := range nodes {
  948. var name = ast.Id2String(node.Name)
  949. if !(isValidFieldName(name)) {
  950. source.ErrorsJoin(errs, source.MakeError(
  951. node.Location,
  952. E_InvalidFieldName {
  953. FieldKind: "input",
  954. FieldName: name,
  955. },
  956. ))
  957. continue
  958. }
  959. var _, duplicate = index[name]
  960. if !(duplicate) {
  961. if saved != nil {
  962. _, duplicate = saved.FieldIndexMap[name]
  963. }
  964. }
  965. if duplicate {
  966. source.ErrorsJoin(errs, source.MakeError(
  967. node.Location,
  968. E_DuplicateField {
  969. FieldKind: "input",
  970. FieldName: name,
  971. },
  972. ))
  973. continue
  974. }
  975. var loc = node.Location
  976. var doc = ast.GetDocContent(node.Docs)
  977. var type_ = makeType(node.Type, ctx)
  978. var default_, has_default = node.Default.(ast.Expr)
  979. if has_default {
  980. *gen = append(*gen, generatedConst {
  981. name: name,
  982. val: funImplAstExpr { default_ },
  983. typ: type_,
  984. loc: default_.Location,
  985. doc: "",
  986. })
  987. }
  988. var info = typsys.FieldInfo {
  989. Info: typsys.Info { Location: loc, Document: doc },
  990. HasDefaultValue: has_default,
  991. }
  992. fields[i] = typsys.Field {
  993. Info: info,
  994. Name: name,
  995. Type: type_,
  996. }
  997. index[name] = i
  998. }
  999. return &typsys.Fields {
  1000. FieldIndexMap: index,
  1001. FieldList: fields,
  1002. }
  1003. } else {
  1004. return &typsys.Fields {}
  1005. }
  1006. }
  1007. func getTypeParamName(rb ast.RefBase, ctx *typeConsContext) (string, bool) {
  1008. var _, ns_specified = rb.NS.(ast.Identifier)
  1009. var ns_not_specified = !(ns_specified)
  1010. var item_name = ast.Id2String(rb.Item)
  1011. if ns_not_specified && ctx.isTypeParameter(item_name) {
  1012. return item_name, true
  1013. } else {
  1014. return "", false
  1015. }
  1016. }
  1017. func getRef(rb ast.RefBase) source.Ref {
  1018. var ns = ast.MaybeId2String(rb.NS)
  1019. var item = ast.Id2String(rb.Item)
  1020. return source.MakeRef(ns, item)
  1021. }
  1022. func isValidFieldName(name string) bool {
  1023. return (name != Underscore)
  1024. }
  1025. const This = "this"
  1026. type unifiedFunDecl struct {
  1027. kind FunKind
  1028. va bool
  1029. name ast.Identifier
  1030. sig ast.FunctionSignature
  1031. loc source.Location
  1032. doc [] ast.Doc
  1033. off bool
  1034. impl funImpl
  1035. }
  1036. type paramMapping (map[string] ([] ast.Identifier))
  1037. func makeParamMapping(stmts ([] ast.VariousStatement)) paramMapping {
  1038. var pm = make(paramMapping)
  1039. for _, stmt := range stmts {
  1040. switch S := stmt.Statement.(type) {
  1041. case ast.DeclType:
  1042. var name = ast.Id2String(S.Name)
  1043. var _, exists = pm[name]
  1044. if !(exists) {
  1045. pm[name] = S.TypeParams
  1046. }
  1047. }
  1048. }
  1049. return pm
  1050. }
  1051. func unifyFunDecl(stmt ast.Statement, pm paramMapping, ns string) *unifiedFunDecl {
  1052. switch S := stmt.(type) {
  1053. case ast.DeclFunction:
  1054. var kind = (func() FunKind {
  1055. if S.Operator {
  1056. return FK_Operator
  1057. } else {
  1058. return FK_Ordinary
  1059. }
  1060. })()
  1061. return &unifiedFunDecl {
  1062. kind: kind,
  1063. va: S.Variadic,
  1064. name: S.Name,
  1065. sig: S.Signature,
  1066. loc: S.Location,
  1067. doc: S.Docs,
  1068. off: S.Off,
  1069. impl: funImplFromAstBody(S.Body),
  1070. }
  1071. case ast.DeclConst:
  1072. var sig = ast.FunctionSignature {
  1073. Node: S.Type.Node,
  1074. Output: S.Type,
  1075. }
  1076. return &unifiedFunDecl {
  1077. kind: FK_Const,
  1078. name: S.Name,
  1079. sig: sig,
  1080. loc: S.Location,
  1081. doc: S.Docs,
  1082. off: S.Off,
  1083. impl: funImplFromAstBody(S.Body),
  1084. }
  1085. case ast.DeclMethod:
  1086. var recv = S.Receiver
  1087. var recv_type, recv_params = getReceiverTypeAndParams(recv, pm, ns)
  1088. var recv_inputs = getReceiverInputs(recv_type)
  1089. var sig = ast.FunctionSignature {
  1090. Node: S.Node,
  1091. TypeParams: recv_params,
  1092. Inputs: recv_inputs,
  1093. Output: S.Type,
  1094. }
  1095. return &unifiedFunDecl {
  1096. kind: FK_Method,
  1097. name: S.Name,
  1098. sig: sig,
  1099. loc: S.Location,
  1100. doc: S.Docs,
  1101. off: S.Off,
  1102. impl: funImplFromAstBody(S.Body),
  1103. }
  1104. case ast.DeclEntry:
  1105. var empty = ast.String2Id("", S.Node)
  1106. var expr = ast.WrapBlockAsExpr(S.Content)
  1107. var ob_none_t = program.AT_Observable(program.AT_None())(S.Node)
  1108. var sig = ast.FunctionSignature {
  1109. Node: S.Node,
  1110. Output: ob_none_t,
  1111. }
  1112. return &unifiedFunDecl {
  1113. kind: FK_Entry,
  1114. name: empty,
  1115. sig: sig,
  1116. loc: S.Location,
  1117. doc: S.Docs,
  1118. off: S.Off,
  1119. impl: funImplAstExpr { expr },
  1120. }
  1121. // case ast.DeclAsset:
  1122. // var name = ast.String2Id(S.Name, S.Node)
  1123. // var path = S.Content.Path
  1124. // var data = S.Content.Data
  1125. // var asset_t = program.AT_Asset()(S.Node)
  1126. // var sig = ast.FunctionSignature {
  1127. // Node: S.Node,
  1128. // Output: asset_t,
  1129. // }
  1130. // return &unifiedFunDecl {
  1131. // kind: FK_Const,
  1132. // name: name,
  1133. // sig: sig,
  1134. // loc: S.Location,
  1135. // impl: funImplLoadedAsset { path, data },
  1136. // }
  1137. default:
  1138. panic("impossible branch")
  1139. }
  1140. }
  1141. func getReceiverTypeAndParams(recv ast.Identifier, pm paramMapping, ns string) (ast.Type, ([] ast.Identifier)) {
  1142. var recv_name = ast.Id2String(recv)
  1143. var recv_params = pm[recv_name]
  1144. var recv_type = ast.Type {
  1145. Node: recv.Node,
  1146. Ref: ast.Ref {
  1147. Node: recv.Node,
  1148. Base: ast.RefBase {
  1149. Node: recv.Node,
  1150. NS: ast.String2Id(ns, recv.Node),
  1151. Item: recv,
  1152. },
  1153. TypeArgs: ctn.MapEach(recv_params, func(param ast.Identifier) ast.Type {
  1154. return ast.Type {
  1155. Node: param.Node,
  1156. Ref: ast.Ref {
  1157. Node: param.Node,
  1158. Base: ast.RefBase {
  1159. Node: param.Node,
  1160. Item: param,
  1161. },
  1162. },
  1163. }
  1164. }),
  1165. },
  1166. }
  1167. return recv_type, recv_params
  1168. }
  1169. func getReceiverInputs(recv_type ast.Type) ast.Inputs {
  1170. var content = ast.RecordDef {
  1171. Node: recv_type.Node,
  1172. Fields: [] ast.Field { {
  1173. Node: recv_type.Node,
  1174. Name: ast.String2Id(This, recv_type.Node),
  1175. Type: recv_type,
  1176. } },
  1177. }
  1178. return ast.Inputs {
  1179. Node: recv_type.Node,
  1180. Content: content,
  1181. }
  1182. }
  1183. func getAssocTypeName(inputs ast.Inputs, kind FunKind, ns string, ctx *typeConsContext) string {
  1184. switch kind {
  1185. case FK_Operator, FK_Method:
  1186. var fields = inputs.Content.Fields
  1187. if len(fields) > 0 {
  1188. var first = fields[0]
  1189. var ref = getRef(first.Type.Ref.Base)
  1190. if ref.Namespace == ns {
  1191. if !((ref.Namespace == "") && ctx.isTypeParameter(ref.ItemName)) {
  1192. return ref.ItemName
  1193. }}
  1194. }
  1195. }
  1196. return ""
  1197. }