expr2.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  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. func checkCallFunRef(callee ast.Ref, arg0 *program.Expr, args ast.VariousPipeCall, infix bool, loc source.Location, cc *exprCheckContext) (*program.Expr, *source.Error) {
  11. var ctx = cc.context
  12. var ref = getRef(callee.Base)
  13. var t0 = getOptionalExprType(arg0)
  14. var ref_loc = callee.Location
  15. var hdr, f, ns, key, err = determineCallee(ref, t0, infix, ref_loc, ctx)
  16. if err != nil { return nil, err }
  17. var Tp = hdr.typeParams
  18. { var Ta, err = getTypeArgs(callee.TypeArgs, ctx)
  19. if err != nil { return nil, err }
  20. var O = hdr.output.type_
  21. var E = hdr.inputsExplicit
  22. var I = hdr.inputsImplicit
  23. var dvg = makeCallFunRefDefaultValueGetter(ns, key, ctx)
  24. var va = hdr.variadic
  25. return cc.infer(Tp, Ta, O, loc, func(cc *exprCheckContext) (program.ExprContent, *source.Error) {
  26. var Ea_, Ia_ = splitRawArgs(args, I)
  27. var Ea = adaptRawArgs(arg0, Ea_)
  28. var Ia = adaptRawArgs(nil, Ia_)
  29. var f_args, err = checkArguments(cc, Ea, E, Tp, dvg, va, loc)
  30. if err != nil { return nil, err }
  31. { var f_ctx, err = checkArguments(cc, Ia, I, Tp, dvg, false, loc)
  32. if err != nil { return nil, err }
  33. return program.CallFunction {
  34. Location: loc,
  35. Callee: f,
  36. Context: f_ctx,
  37. Arguments: f_args,
  38. }, nil }
  39. })}
  40. }
  41. func checkNewRecord(record ast.Ref, args ast.VariousPipeCall, tag string, loc source.Location, cc *exprCheckContext) (*program.Expr, *source.Error) {
  42. var ctx = cc.context
  43. var ref = getRef(record.Base)
  44. var def, exists = ctx.resolveType(ref)
  45. if !(exists) { return cc.error(loc, E_NoSuchType { ref.String() }) }
  46. var R_, ok = def.Content.(typsys.Record)
  47. if !(ok) { return cc.error(loc, E_NotRecord { ref.String() }) }
  48. var rt, tag_valid = getRecordTransform(tag)
  49. if !(tag_valid) { return cc.error(loc, E_InvalidRecordTag { tag }) }
  50. var R = rt.fields.apply(R_.Fields)
  51. var Ra = adaptRawArgs(nil, args)
  52. var Tp = def.Parameters
  53. var Ta, err = getTypeArgs(record.TypeArgs, ctx)
  54. if err != nil { return nil, err }
  55. var output = rt.recordType.apply(typsys.DefType(def))
  56. var dvt = makeDefaultValueTransform(rt)
  57. var dvg = makeNewRecordDefaultValueGetter(ref, dvt, ctx)
  58. return cc.infer(Tp, Ta, output, loc, func(cc *exprCheckContext) (program.ExprContent, *source.Error) {
  59. var values, err = checkArguments(cc, Ra, R, Tp, dvg, false, loc)
  60. if err != nil { return nil, err }
  61. return rt.recordValue.apply(program.Record { Values: values }), nil
  62. })
  63. }
  64. func checkCallExpr(callee ast.Expr, args ast.VariousPipeCall, cc *exprCheckContext) (*program.Expr, *source.Error) {
  65. var loc = args.Location
  66. var callee_expr, err = cc.checkChildExpr(nil, callee)
  67. if err != nil { return nil, err }
  68. if in_t, out_t, sam, ok := cc.getCallable(callee_expr.Type); ok {
  69. if sam {
  70. var lambda_t_ = program.T_Lambda(in_t.Type, out_t.Type)
  71. var lambda_t = typsys.CertainType { Type: lambda_t_ }
  72. callee_expr = &program.Expr {
  73. Type: lambda_t,
  74. Info: callee_expr.Info,
  75. Content: program.AbstractMethodValue {
  76. Interface: callee_expr,
  77. Index: 0,
  78. },
  79. }
  80. }
  81. var arg_t = in_t
  82. var arg_spec = getLambdaParameters(arg_t)
  83. var arg_content, err = checkLambdaArguments(arg_spec, args, cc)
  84. if err != nil { return nil, err }
  85. var arg_expr = &program.Expr {
  86. Type: arg_t,
  87. Info: program.ExprInfoFrom(loc),
  88. Content: arg_content,
  89. }
  90. return cc.assign(out_t, loc,
  91. program.CallLambda {
  92. Callee: callee_expr,
  93. Argument: arg_expr,
  94. })
  95. } else {
  96. return cc.error(loc,
  97. E_NotCallable {
  98. TypeDesc: typsys.DescribeCertain(callee_expr.Type),
  99. })
  100. }
  101. }
  102. func (cc *exprCheckContext) getCallable(t typsys.CertainType) (typsys.CertainType, typsys.CertainType, bool, bool) {
  103. var sam = false
  104. var in, out, ok = program.T_Lambda_(t.Type)
  105. if !(ok) {
  106. if t, sam_ok := getSamInterfaceMethodType(t.Type, cc.context); sam_ok {
  107. sam = true
  108. in, out, ok = program.T_Lambda_(t)
  109. }
  110. }
  111. if ok {
  112. var in_t = typsys.CertainType { Type: in }
  113. var out_t = typsys.CertainType { Type: out }
  114. return in_t, out_t, sam, true
  115. } else {
  116. var nil_t typsys.CertainType
  117. return nil_t, nil_t, false, false
  118. }
  119. }
  120. func checkRefTerm(ref_term ast.RefTerm, cc *exprCheckContext) (*program.Expr, *source.Error) {
  121. var ctx = cc.context
  122. var loc = ref_term.Location
  123. var ref_node = ref_term.Ref
  124. var _, is_new = ref_term.New.(ast.New)
  125. if is_new {
  126. return cc.error(loc,
  127. E_InvalidConstructorUsage {})
  128. }
  129. var ref = getRef(ref_node.Base)
  130. if ref.Namespace == "" {
  131. if binding, ok := ctx.useBinding(ref.ItemName); ok {
  132. if len(ref_node.TypeArgs) > 0 {
  133. return cc.error(loc,
  134. E_SuperfluousTypeArgs {})
  135. }
  136. return cc.assign(binding.Type, loc,
  137. program.LocalRef {
  138. Binding: binding,
  139. })
  140. }
  141. if t, ok := cc.getExpectedCertainOrInferred(); ok {
  142. if e, _, ok := getEnum(t.Type, ctx); ok {
  143. if index, ok := e.FieldIndexMap[ref.ItemName]; ok {
  144. return cc.assign(t, loc,
  145. program.Enum (
  146. index,
  147. ))
  148. }}}
  149. }
  150. var Ta, err = getTypeArgs(ref_term.Ref.TypeArgs, ctx)
  151. if err != nil { return nil, err }
  152. var options = findFunRefOptions(ref, ctx)
  153. if len(options) == 0 {
  154. return cc.error(loc, E_NoSuchThing { ref.String() })
  155. }
  156. var names = ctn.MapEach(options, func(option func()(*funHeader,**program.Function,string)) string {
  157. var _, _, name = option()
  158. return name
  159. })
  160. var trials = ctn.MapEach(options, func(option func()(*funHeader,**program.Function,string)) func()(*program.Expr,**typsys.InferringState,*source.Error) {
  161. var hdr, f, _ = option()
  162. return func() (*program.Expr, **typsys.InferringState, *source.Error) {
  163. var Tp = hdr.typeParams
  164. var O = hdr.output.type_
  165. var E = hdr.inputsExplicit
  166. var I = hdr.inputsImplicit
  167. if hdr.funKind == FK_Const {
  168. if len(Tp) > 0 {
  169. panic("something went wrong")
  170. }
  171. if len(Ta) > 0 {
  172. return nil, nil, source.MakeError(loc,
  173. E_SuperfluousTypeArgs {})
  174. }
  175. if len(E.FieldList) > 0 || len(I.FieldList) > 0 {
  176. panic("something went wrong")
  177. }
  178. var t = typsys.CertainType { Type: O }
  179. return cc.tryAssign(t, loc,
  180. program.CallFunction {
  181. Location: loc,
  182. Callee: f,
  183. })
  184. } else {
  185. if len(I.FieldList) > 0 {
  186. return nil, nil, source.MakeError(loc,
  187. E_CannotAssignFunctionRequiringImplicitInput {})
  188. }
  189. var L, unpack, ok = makeLambdaType(E, O)
  190. if !(ok) {
  191. return nil, nil, source.MakeError(loc,
  192. E_UnableToUseAsLambda { describeFunInOut(hdr) })
  193. }
  194. return cc.tryInfer(Tp, Ta, L, loc, func(cc *exprCheckContext) (program.ExprContent, *source.Error) {
  195. return program.FunRef {
  196. Function: f,
  197. Unpack: unpack,
  198. }, nil
  199. })
  200. }
  201. }
  202. })
  203. var ref_expr *program.Expr
  204. var ref_S **typsys.InferringState
  205. var found = false
  206. var details = make([] NoneAssignableErrorDetail, 0)
  207. for i, trial := range trials {
  208. var expr, S, err = trial()
  209. if err == nil {
  210. if found {
  211. return cc.error(loc,
  212. E_MultipleAssignable { ref.String() })
  213. } else {
  214. ref_expr = expr
  215. ref_S = S
  216. found = true
  217. }
  218. } else {
  219. details = append(details, NoneAssignableErrorDetail {
  220. ItemName: names[i],
  221. ErrorContent: err.Content,
  222. })
  223. }
  224. }
  225. if found {
  226. cc.loadTrialInferringState(ref_S)
  227. return ref_expr, nil
  228. } else {
  229. return cc.error(loc,
  230. E_NoneAssignable { ref.String(), details })
  231. }
  232. }
  233. func checkImplicitRefTerm(I ast.ImplicitRefTerm, cc *exprCheckContext) (*program.Expr, *source.Error) {
  234. var name = ast.Id2String(I.Name)
  235. var ref_node = (func() ast.Ref {
  236. if P, item, ok := ast.SplitImplicitRef(name); ok {
  237. if s := cc.getInferringState(); s != nil {
  238. if ns, ok := s.GetInferredParameterNamespace(P); ok {
  239. return ast.Strings2Ref(ns, item, I.Node)
  240. }}}
  241. return ast.String2Ref(name, I.Node)
  242. })()
  243. var ref_term = ast.RefTerm {
  244. Node: ref_node.Node,
  245. Ref: ref_node,
  246. }
  247. return checkRefTerm(ref_term, cc)
  248. }
  249. type arguments ([] argument)
  250. type argument struct {
  251. name string
  252. expr *program.Expr
  253. node *ast.Expr
  254. }
  255. func (arg argument) getName() (string, bool) {
  256. return arg.name, (arg.name != "")
  257. }
  258. func (arg argument) getExpr() (*program.Expr, bool) {
  259. return arg.expr, (arg.expr != nil)
  260. }
  261. func (arg argument) getNode() (*ast.Expr, bool) {
  262. return arg.node, (arg.node != nil)
  263. }
  264. func (arg argument) getLocation() source.Location {
  265. if expr, ok := arg.getExpr(); ok {
  266. return expr.Info.Location
  267. } else if node, ok := arg.getNode(); ok {
  268. return node.Location
  269. } else {
  270. panic("impossible branch")
  271. }
  272. }
  273. func (arg argument) check(cc *exprCheckContext, expected typsys.Type) (*program.Expr, *source.Error) {
  274. if expr, ok := arg.getExpr(); ok {
  275. return cc.assignChildExpr(expected, expr)
  276. } else if node, ok := arg.getNode(); ok {
  277. return cc.checkChildExpr(expected, *node)
  278. } else {
  279. panic("impossible branch")
  280. }
  281. }
  282. func adaptRawArgs(raw0 *program.Expr, raw ast.VariousPipeCall) arguments {
  283. var result = make(arguments, 0)
  284. if raw0 != nil {
  285. result = append(result, argument {
  286. expr: raw0,
  287. })
  288. }
  289. switch R := raw.PipeCall.(type) {
  290. case ast.CallOrdered:
  291. for i := range R.Arguments {
  292. result = append(result, argument {
  293. node: &(R.Arguments[i]),
  294. })
  295. }
  296. case ast.CallUnordered:
  297. for _, mapping := range R.Mappings {
  298. var name = ast.Id2String(mapping.Name)
  299. var node = getArgMappingExprNode(mapping.Name, mapping.Value)
  300. result = append(result, argument {
  301. name: name,
  302. node: node,
  303. })
  304. }
  305. }
  306. return result
  307. }
  308. func getArgMappingExprNode(k ast.Identifier, v ast.MaybeExpr) *ast.Expr {
  309. if node, ok := v.(ast.Expr); ok {
  310. return &node
  311. } else {
  312. var node = ast.WrapTermAsExpr(ast.VariousTerm {
  313. Node: k.Node,
  314. Term: ast.RefTerm {
  315. Node: k.Node,
  316. Ref: ast.Ref {
  317. Node: k.Node,
  318. Base: ast.RefBase {
  319. Node: k.Node,
  320. Item: k,
  321. },
  322. },
  323. },
  324. })
  325. return &node
  326. }
  327. }
  328. func splitRawArgs(raw ast.VariousPipeCall, imp_spec *typsys.Fields) (ast.VariousPipeCall, ast.VariousPipeCall) {
  329. var imp_mappings = make([] ast.ArgumentMapping, len(imp_spec.FieldList))
  330. var imp_is_set = make([] bool, len(imp_spec.FieldList))
  331. var explicit = (func() ast.VariousPipeCall {
  332. switch R := raw.PipeCall.(type) {
  333. case ast.CallOrdered:
  334. return raw
  335. case ast.CallUnordered:
  336. var exp_mappings = make([] ast.ArgumentMapping, 0)
  337. for _, mapping := range R.Mappings {
  338. var name = ast.Id2String(mapping.Name)
  339. var index, is_imp = imp_spec.FieldIndexMap[name]
  340. if is_imp {
  341. imp_mappings[index] = mapping
  342. imp_is_set[index] = true
  343. } else {
  344. exp_mappings = append(exp_mappings, mapping)
  345. }
  346. }
  347. return ast.VariousPipeCall {
  348. Node: raw.Node,
  349. PipeCall: ast.CallUnordered {
  350. Node: raw.Node,
  351. Mappings: exp_mappings,
  352. },
  353. }
  354. default:
  355. panic("impossible branch")
  356. }
  357. })()
  358. var implicit = (func() ast.VariousPipeCall {
  359. for i := range imp_mappings {
  360. if !(imp_is_set[i]) {
  361. var name = imp_spec.FieldList[i].Name
  362. imp_mappings[i] = ast.ArgumentMapping {
  363. Node: raw.Node,
  364. Name: ast.String2Id(name, raw.Node),
  365. Value: ast.WrapTermAsExpr(ast.VariousTerm {
  366. Node: raw.Node,
  367. Term: ast.ImplicitRefTerm {
  368. Node: raw.Node,
  369. Name: ast.String2Id(name, raw.Node),
  370. },
  371. }),
  372. }
  373. }
  374. }
  375. return ast.VariousPipeCall {
  376. Node: raw.Node,
  377. PipeCall: ast.CallUnordered {
  378. Node: raw.Node,
  379. Mappings: imp_mappings,
  380. },
  381. }
  382. })()
  383. return explicit, implicit
  384. }
  385. type defaultValueGetter struct {
  386. fragment fragmentDraft
  387. namespace string
  388. funName string
  389. typeName string
  390. transform defaultValueTransform
  391. }
  392. func makeCallFunRefDefaultValueGetter(f_ns string, f_key userFunKey, ctx *exprContext) defaultValueGetter {
  393. return defaultValueGetter {
  394. fragment: ctx.fragment,
  395. namespace: f_ns,
  396. funName: f_key.name,
  397. typeName: f_key.assoc,
  398. }
  399. }
  400. func makeNewRecordDefaultValueGetter(ref source.Ref, dvt defaultValueTransform, ctx *exprContext) defaultValueGetter {
  401. return defaultValueGetter {
  402. fragment: ctx.fragment,
  403. namespace: ref.Namespace,
  404. typeName: ref.ItemName,
  405. transform: dvt,
  406. }
  407. }
  408. func (dvg defaultValueGetter) get(field_name string) **program.Function {
  409. var ns = dvg.namespace
  410. var key = genFunKey {
  411. typeName: dvg.typeName,
  412. funName: dvg.funName,
  413. fieldName: field_name,
  414. }
  415. return dvg.fragment.referGenFun(ns, key)
  416. }
  417. func checkArguments (
  418. cc *exprCheckContext,
  419. args arguments,
  420. fields *typsys.Fields,
  421. inf ([] string),
  422. dvg defaultValueGetter,
  423. va bool,
  424. loc source.Location,
  425. ) ([] *program.Expr, *source.Error) {
  426. var arity = len(fields.FieldList)
  427. var last = (arity - 1)
  428. var result = make([] *program.Expr, arity)
  429. var ordered_count = 0
  430. var unordered = make(map[string] int)
  431. var used = make([] bool, len(args))
  432. for i, arg := range args {
  433. if arg.name == "" {
  434. if len(unordered) > 0 { panic("something went wrong") }
  435. ordered_count += 1
  436. } else {
  437. var name = arg.name
  438. if _, duplicate := unordered[name]; duplicate {
  439. return nil, source.MakeError(arg.getLocation(),
  440. E_DuplicateArgument {
  441. Name: name,
  442. })
  443. }
  444. unordered[name] = i
  445. }
  446. }
  447. for i, field := range fields.FieldList {
  448. var field_name = field.Name
  449. var field_type = typsys.ToInferring(field.Type, inf)
  450. var field_has_default = field.Info.HasDefaultValue
  451. if va && (len(unordered) == 0) && (i == last) {
  452. var pos0 = i
  453. var va_type, ok = program.T_List_(field_type)
  454. if !(ok) {
  455. // error should have been reported on function signature
  456. break
  457. }
  458. var va_list = (func() arguments {
  459. if pos0 < len(args) {
  460. return args[pos0:]
  461. } else {
  462. return nil
  463. }
  464. })()
  465. var va_expr_list = make([] *program.Expr, len(va_list))
  466. for j, va_item := range va_list {
  467. var expr, err = va_item.check(cc, va_type)
  468. if err != nil { return nil, err }
  469. va_expr_list[j] = expr
  470. }
  471. for pos := pos0; pos < len(args); pos += 1 {
  472. used[pos] = true
  473. }
  474. if va_certain, ok := cc.getCertainOrInferred(va_type); ok {
  475. result[i] = &program.Expr {
  476. Type: va_certain,
  477. Info: program.ExprInfoFrom(loc),
  478. Content: program.List { Items: va_expr_list },
  479. }
  480. } else {
  481. return nil, source.MakeError(loc,
  482. E_UnableToInferVaType {})
  483. }
  484. } else {
  485. if pos, ok := (func() (int, bool) {
  486. if i < ordered_count {
  487. return i, true
  488. } else if pos, ok := unordered[field_name]; ok {
  489. return pos, true
  490. } else {
  491. return -1, false
  492. }
  493. })(); ok {
  494. var arg = args[pos]
  495. if used[pos] {
  496. return nil, source.MakeError(arg.getLocation(),
  497. E_DuplicateArgument {
  498. Name: field_name,
  499. })
  500. }
  501. used[pos] = true
  502. var expr, err = arg.check(cc, field_type)
  503. if err != nil { return nil, err }
  504. result[i] = expr
  505. } else {
  506. if field_has_default {
  507. if field_t, ok := cc.getCertainOrInferred(field_type); ok {
  508. var f = dvg.get(field_name)
  509. var expr = &program.Expr {
  510. Type: field_t,
  511. Info: program.ExprInfoFrom(loc),
  512. Content: dvg.transform.apply(program.CallFunction {
  513. Location: loc,
  514. Callee: f,
  515. }),
  516. }
  517. result[i] = expr
  518. } else {
  519. return nil, source.MakeError(loc,
  520. E_UnableToInferDefaultValueType {
  521. ArgName: field_name,
  522. })
  523. }
  524. } else {
  525. return nil, source.MakeError(loc,
  526. E_MissingArgument {
  527. Name: field_name,
  528. })
  529. }
  530. }
  531. }
  532. }
  533. for pos, used := range used {
  534. if !(used) {
  535. var arg = args[pos]
  536. return nil, source.MakeError(arg.getLocation(),
  537. E_SuperfluousArgument {})
  538. }
  539. }
  540. return result, nil
  541. }
  542. func makeLambdaType(inputs *typsys.Fields, output typsys.Type) (typsys.Type, bool, bool) {
  543. const keep = false
  544. const unpack = true
  545. var args = inputs.FieldList
  546. var ret = output
  547. var arity = len(args)
  548. if arity == 1 {
  549. var arg = args[0].Type
  550. return program.T_Lambda(arg, ret), keep, true
  551. } else if arity == 2 {
  552. var arg = program.T_Pair(args[0].Type, args[1].Type)
  553. return program.T_Lambda(arg, ret), unpack, true
  554. } else if arity == 3 {
  555. var arg = program.T_Triple(args[0].Type, args[1].Type, args[2].Type)
  556. return program.T_Lambda(arg, ret), unpack, true
  557. } else {
  558. return nil, false, false
  559. }
  560. }
  561. func getLambdaParameters(in_t typsys.CertainType) ([] typsys.CertainType) {
  562. if program.T_Null_(in_t.Type) {
  563. return [] typsys.CertainType {}
  564. }
  565. if a_, b_, ok := program.T_Pair_(in_t.Type); ok {
  566. var a = typsys.CertainType { Type: a_ }
  567. var b = typsys.CertainType { Type: b_ }
  568. return [] typsys.CertainType { a, b }
  569. }
  570. if a_, b_, c_, ok := program.T_Triple_(in_t.Type); ok {
  571. var a = typsys.CertainType { Type: a_ }
  572. var b = typsys.CertainType { Type: b_ }
  573. var c = typsys.CertainType { Type: c_ }
  574. return [] typsys.CertainType { a, b, c }
  575. }
  576. return [] typsys.CertainType { in_t }
  577. }
  578. func checkLambdaArguments(params ([] typsys.CertainType), args ast.VariousPipeCall, cc *exprCheckContext) (program.ExprContent, *source.Error) {
  579. var loc = args.Location
  580. switch args := args.PipeCall.(type) {
  581. case ast.CallOrdered:
  582. var given = len(args.Arguments)
  583. var required = len(params)
  584. if given != required {
  585. return nil, source.MakeError(loc,
  586. E_LambdaCallWrongArgsQuantity {
  587. Given: given,
  588. Required: required,
  589. })
  590. }
  591. var expr_list = make([] *program.Expr, len(params))
  592. for i, p := range params {
  593. var expr, err = cc.checkChildExpr(p.Type, args.Arguments[i])
  594. if err != nil { return nil, err }
  595. expr_list[i] = expr
  596. }
  597. var n = len(expr_list)
  598. if n == 0 {
  599. return program.Null {}, nil
  600. } else if n == 1 {
  601. return expr_list[0].Content, nil
  602. } else {
  603. return program.Record { Values: expr_list }, nil
  604. }
  605. case ast.CallUnordered:
  606. return nil, source.MakeError(loc,
  607. E_LambdaCallUnorderedArgs {})
  608. default:
  609. panic("impossible branch")
  610. }
  611. }
  612. type transform[T any] struct {
  613. f func(T) T
  614. }
  615. func makeTransform[T any] (f func(T)(T)) transform[T] {
  616. return transform[T] { f }
  617. }
  618. func (t transform[T]) apply(v T) T {
  619. if t.f != nil {
  620. return t.f(v)
  621. } else {
  622. return v
  623. }
  624. }
  625. type defaultValueTransform struct {
  626. transform[program.ExprContent]
  627. }
  628. func makeDefaultValueTransform(rt recordTransform) defaultValueTransform {
  629. return defaultValueTransform { rt.fieldDefault }
  630. }
  631. type recordTransform struct {
  632. fields transform[*typsys.Fields]
  633. recordType transform[typsys.Type]
  634. fieldDefault transform[program.ExprContent]
  635. recordValue transform[program.ExprContent]
  636. }
  637. func getRecordTransform(tag string) (recordTransform, bool) {
  638. switch tag {
  639. case "":
  640. return recordTransform {}, true
  641. case program.T_Observable_Tag:
  642. return recordTransform {
  643. fields: makeTransform(func(fields *typsys.Fields) *typsys.Fields {
  644. return mapFieldsType(fields, program.T_Observable)
  645. }),
  646. recordType: makeTransform(func(t typsys.Type) typsys.Type {
  647. return program.T_Observable(t)
  648. }),
  649. fieldDefault: makeTransform(func(e program.ExprContent) program.ExprContent {
  650. return program.ObservableRecordDefault {
  651. Content: e,
  652. }
  653. }),
  654. recordValue: makeTransform(func(e program.ExprContent) program.ExprContent {
  655. return program.ObservableRecord {
  656. Record: e.(program.Record),
  657. }
  658. }),
  659. }, true
  660. case program.T_Observable_Maybe_Tag:
  661. return recordTransform {
  662. fields: makeTransform(func(fields *typsys.Fields) *typsys.Fields {
  663. return mapFieldsType(mapFieldsType(fields,
  664. program.T_Maybe), program.T_Observable)
  665. }),
  666. recordType: makeTransform(func(t typsys.Type) typsys.Type {
  667. return program.T_Observable(program.T_Maybe(t))
  668. }),
  669. fieldDefault: makeTransform(func(e program.ExprContent) program.ExprContent {
  670. return program.ObservableMaybeRecordDefault {
  671. Content: e,
  672. }
  673. }),
  674. recordValue: makeTransform(func(e program.ExprContent) program.ExprContent {
  675. return program.ObservableMaybeRecord {
  676. Record: e.(program.Record),
  677. }
  678. }),
  679. }, true
  680. case program.T_Hook_Tag:
  681. return recordTransform {
  682. fields: makeTransform(func(fields *typsys.Fields) *typsys.Fields {
  683. return mapFieldsType(fields, program.T_Hook)
  684. }),
  685. recordType: makeTransform(func(t typsys.Type) typsys.Type {
  686. return program.T_Hook(t)
  687. }),
  688. fieldDefault: makeTransform(func(e program.ExprContent) program.ExprContent {
  689. return program.HookRecordDefault {
  690. Content: e,
  691. }
  692. }),
  693. recordValue: makeTransform(func(e program.ExprContent) program.ExprContent {
  694. return program.HookRecord {
  695. Record: e.(program.Record),
  696. }
  697. }),
  698. }, true
  699. default:
  700. return recordTransform {}, false
  701. }
  702. }
  703. func mapFieldsType(fields *typsys.Fields, f func(typsys.Type)(typsys.Type)) *typsys.Fields {
  704. var m = make(map[string] int)
  705. for k, v := range fields.FieldIndexMap {
  706. m[k] = v
  707. }
  708. var l = ctn.MapEach(fields.FieldList, func(field typsys.Field) typsys.Field {
  709. return typsys.Field {
  710. Info: field.Info,
  711. Name: field.Name,
  712. Type: f(field.Type),
  713. }
  714. })
  715. return &typsys.Fields {
  716. FieldIndexMap: m,
  717. FieldList: l,
  718. }
  719. }
  720. func findFunRefOptions(ref source.Ref, ctx *exprContext) ([] func()(*funHeader,**program.Function,string)) {
  721. var all = ctx.context.lookupAssignableKindFunctions(ref)
  722. if len(all) == 0 {
  723. if ctx.tryRedirectRef(&ref) {
  724. all = ctx.context.lookupAssignableKindFunctions(ref)
  725. }
  726. }
  727. return ctn.MapEach(all, func(item func()(*funHeader,string,userFunKey)) func()(*funHeader,**program.Function,string) {
  728. var hdr, ns, key = item()
  729. var f = ctx.fragment.referUserFun(ns, key)
  730. var name = key.Describe(ns)
  731. var option = func() (*funHeader, **program.Function, string) {
  732. return hdr, f, name
  733. }
  734. return option
  735. })
  736. }
  737. func determineCallee(ref source.Ref, t0 ctn.Maybe[typsys.CertainType], infix bool, loc source.Location, ctx *exprContext) (*funHeader, **program.Function, string, userFunKey, *source.Error) {
  738. var r0 = getTypeAssocRef(t0)
  739. var kind = (func() FunKind {
  740. if infix {
  741. return FK_Operator
  742. } else {
  743. return FK_Ordinary
  744. }
  745. })()
  746. var hdr, ns, key, ok = ctx.context.lookupFunction(ref, r0, kind)
  747. if !(ok) {
  748. if ctx.tryRedirectRef(&ref) {
  749. hdr, ns, key, ok = ctx.context.lookupFunction(ref, r0, kind)
  750. }
  751. }
  752. if ok {
  753. return hdr, ctx.fragment.referUserFun(ns, key), ns, key, nil
  754. } else {
  755. var kind_desc = (func() string {
  756. if kind == FK_Operator {
  757. return "operator"
  758. } else {
  759. return "function"
  760. }
  761. })()
  762. var buf strings.Builder
  763. buf.WriteString(ref.String())
  764. if r0, ok := r0.Value(); ok {
  765. if r0.Namespace == ref.Namespace {
  766. buf.WriteRune('(')
  767. buf.WriteString(r0.ItemName)
  768. buf.WriteRune(')')
  769. }}
  770. var name_desc = buf.String()
  771. return nil, nil, "", userFunKey{}, source.MakeError(loc,
  772. E_NoSuchFunction {
  773. FunKindDesc: kind_desc,
  774. FunNameDesc: name_desc,
  775. })
  776. }
  777. }
  778. func getOptionalExprType(expr *program.Expr) ctn.Maybe[typsys.CertainType] {
  779. if expr != nil {
  780. return ctn.Just(expr.Type)
  781. } else {
  782. return nil
  783. }
  784. }
  785. func getTypeAssocRef(t ctn.Maybe[typsys.CertainType]) ctn.Maybe[source.Ref] {
  786. if t, ok := t.Value(); ok {
  787. if ref_type, ok := t.Type.(typsys.RefType); ok {
  788. return ctn.Just(ref_type.Def)
  789. }
  790. }
  791. return nil
  792. }
  793. func getTypeArgs(nodes ([] ast.Type), ctx *exprContext) ([] typsys.CertainType, *source.Error) {
  794. var args = make([] typsys.CertainType, len(nodes))
  795. for i, node := range nodes {
  796. var t, err = ctx.makeType(node)
  797. if err != nil { return nil, err }
  798. args[i] = t
  799. }
  800. return args, nil
  801. }
  802. func craftInfixRight(r ast.Expr, node ast.Node) ast.VariousPipeCall {
  803. return ast.VariousPipeCall {
  804. Node: node,
  805. PipeCall: ast.CallOrdered {
  806. Node: node,
  807. Arguments: [] ast.Expr { r },
  808. },
  809. }
  810. }
  811. func describeFunInOut(hdr *funHeader) string {
  812. var inputs = hdr.inputsExplicit.FieldList
  813. var output = hdr.output
  814. var buf strings.Builder
  815. buf.WriteRune('{')
  816. if len(inputs) > 0 {
  817. buf.WriteRune(' ')
  818. for i, item := range inputs {
  819. buf.WriteString(item.Name)
  820. buf.WriteRune(' ')
  821. buf.WriteString(typsys.Describe(item.Type))
  822. if i != (len(inputs) - 1) {
  823. buf.WriteRune(',')
  824. buf.WriteRune(' ')
  825. }
  826. }
  827. buf.WriteRune(' ')
  828. }
  829. buf.WriteRune('}')
  830. buf.WriteRune(' ')
  831. buf.WriteString(typsys.Describe(output.type_))
  832. return buf.String()
  833. }