header.go 32 KB

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