@harmoniclabs/pebble 0.1.2 → 0.1.3-dev0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,6 +11,7 @@ export declare const hoisted_isTwo: IRHoisted;
11
11
  export declare const hoisted_isThree: IRHoisted;
12
12
  export declare const hoisted_addOne: IRHoisted;
13
13
  export declare const hoisted_subOne: IRHoisted;
14
+ export declare const hoisted_negateInteger: IRHoisted;
14
15
  export declare const hoisted_isPositive: IRHoisted;
15
16
  export declare const hoisted_isNonNegative: IRHoisted;
16
17
  export declare const hoisted_matchList: IRHoisted;
@@ -17,6 +17,7 @@ import { _ir_lazyChooseList } from "../../../tree_utils/_ir_lazyChooseList.js";
17
17
  import { _ir_lazyIfThenElse } from "../../../tree_utils/_ir_lazyIfThenElse.js";
18
18
  import { hoisted_drop4, hoisted_drop2, hoisted_drop3 } from "../_comptimeDropN.js";
19
19
  import { IRConstr } from "../../../IRNodes/index.js";
20
+ import { _ir_and, _ir_or } from "../../../../compiler/tir/expressions/binary/TirBinaryExpr.js";
20
21
  function _ir_strictAnd(left, right) {
21
22
  return _ir_apps(IRNative.strictIfThenElse, left, right, IRConst.bool(false));
22
23
  }
@@ -43,6 +44,8 @@ export const hoisted_addOne = new IRHoisted(new IRApp(IRNative.addInteger, IRCon
43
44
  hoisted_addOne.hash;
44
45
  export const hoisted_subOne = new IRHoisted(new IRApp(IRNative.addInteger, IRConst.int(-1)));
45
46
  hoisted_subOne.hash;
47
+ export const hoisted_negateInteger = new IRHoisted(new IRApp(IRNative.subtractInteger, IRConst.int(0)));
48
+ hoisted_negateInteger.hash;
46
49
  export const hoisted_isPositive = new IRHoisted(new IRApp(IRNative.lessThanInteger, IRConst.int(0)));
47
50
  hoisted_isPositive.hash;
48
51
  export const hoisted_isNonNegative = new IRHoisted(new IRApp(IRNative.lessThanEqualInteger, IRConst.int(0)));
@@ -54,6 +57,7 @@ export const hoisted_matchList = new IRHoisted((() => {
54
57
  return new IRFunc([delayed_matchNil, matchCons, list], new IRForced(new IRForced(_ir_apps(IRNative.strictChooseList, new IRVar(list), new IRVar(delayed_matchNil), new IRDelayed(_ir_apps(new IRVar(matchCons), new IRApp(IRNative.headList, new IRVar(list)), new IRApp(IRNative.tailList, new IRVar(list))))))));
55
58
  })());
56
59
  hoisted_matchList.hash;
60
+ //*
57
61
  // hoisted_recursiveList (needed by hoisted_foldr)
58
62
  const recList_matchNil = Symbol("matchNil");
59
63
  const recList_matchCons = Symbol("matchCons");
@@ -61,14 +65,15 @@ const recList_self = Symbol("recursiveList_self");
61
65
  const recList_lst = Symbol("lst");
62
66
  export const hoisted_recursiveList = new IRHoisted(new IRFunc([recList_matchNil, recList_matchCons], new IRRecursive(recList_self, new IRFunc([recList_lst], _ir_apps(hoisted_matchList.clone(), new IRApp(new IRVar(recList_matchNil), new IRSelfCall(recList_self)), new IRApp(new IRVar(recList_matchCons), new IRSelfCall(recList_self)), new IRVar(recList_lst))))));
63
67
  hoisted_recursiveList.hash;
68
+ //*/
64
69
  // hoisted_foldr
65
- const foldr_reduce = Symbol("reduceFunc");
70
+ const foldr_reducer = Symbol("reduceFunc");
66
71
  const foldr_acc = Symbol("accumulator");
67
72
  const foldr__dummy = Symbol("_self");
68
73
  const foldr_self = Symbol("self");
69
74
  const foldr_head = Symbol("head");
70
75
  const foldr_tail = Symbol("tail");
71
- export const hoisted_foldr = new IRHoisted(new IRFunc([foldr_reduce, foldr_acc], _ir_apps(hoisted_recursiveList.clone(), new IRFunc([foldr__dummy], new IRDelayed(new IRVar(foldr_acc))), new IRFunc([foldr_self, foldr_head, foldr_tail], _ir_apps(new IRVar(foldr_reduce), new IRVar(foldr_head), new IRApp(new IRVar(foldr_self), new IRVar(foldr_tail)))))));
76
+ export const hoisted_foldr = new IRHoisted(new IRFunc([foldr_reducer, foldr_acc], _ir_apps(hoisted_recursiveList.clone(), new IRFunc([foldr__dummy], new IRDelayed(new IRVar(foldr_acc))), new IRFunc([foldr_self, foldr_head, foldr_tail], _ir_apps(new IRVar(foldr_reducer), new IRVar(foldr_head), new IRApp(new IRVar(foldr_self), new IRVar(foldr_tail)))))));
72
77
  hoisted_foldr.hash;
73
78
  export const hosited_lazyChooseList = new IRHoisted((() => {
74
79
  const list = Symbol("list");
@@ -142,19 +147,25 @@ export const hoisted_strictOr = new IRHoisted(new IRFunc([strictOr_a, strictOr_b
142
147
  hoisted_strictOr.hash;
143
148
  // hoisted _some
144
149
  const some_pred = Symbol("predicate");
145
- const some_dummy = Symbol("_self");
150
+ const some_lst = Symbol("lst");
146
151
  const some_self = Symbol("self");
147
- const some_head = Symbol("head");
148
- const some_tail = Symbol("tail");
149
- export const hoisted_some = new IRHoisted(new IRFunc([some_pred], _ir_apps(hoisted_recursiveList.clone(), new IRFunc([some_dummy], new IRDelayed(IRConst.bool(false))), new IRFunc([some_self, some_head, some_tail], new IRForced(_ir_apps(hoisted_strictOr.clone(), new IRDelayed(new IRApp(new IRVar(some_pred), new IRVar(some_head))), new IRDelayed(new IRApp(new IRVar(some_self), new IRVar(some_tail)))))))));
152
+ export const hoisted_some = new IRHoisted(new IRFunc([some_pred], new IRRecursive(some_self, new IRFunc([some_lst], _ir_lazyChooseList(new IRVar(some_lst), IRConst.bool(false), // case nil => false
153
+ _ir_or(
154
+ // either predicate(head) is true
155
+ _ir_apps(new IRVar(some_pred), new IRApp(IRNative.headList, new IRVar(some_lst))),
156
+ // or self(tail) is true
157
+ _ir_apps(new IRSelfCall(some_self), new IRApp(IRNative.tailList, new IRVar(some_lst)))))))));
150
158
  hoisted_some.hash;
151
159
  // hoisted _every
152
160
  const every_pred = Symbol("predicate");
153
- const every_dummy = Symbol("_self");
154
161
  const every_self = Symbol("self");
155
- const every_head = Symbol("head");
156
- const every_tail = Symbol("tail");
157
- export const hoisted_every = new IRHoisted(new IRFunc([every_pred], _ir_apps(hoisted_recursiveList.clone(), new IRFunc([every_dummy], new IRDelayed(IRConst.bool(true))), new IRFunc([every_self, every_head, every_tail], new IRForced(_ir_apps(hoisted_strictAnd.clone(), new IRDelayed(new IRApp(new IRVar(every_pred), new IRVar(every_head))), new IRDelayed(new IRApp(new IRVar(every_self), new IRVar(every_tail)))))))));
162
+ const every_lst = Symbol("lst");
163
+ export const hoisted_every = new IRHoisted(new IRFunc([every_pred], new IRRecursive(every_self, new IRFunc([every_lst], _ir_lazyChooseList(new IRVar(every_lst), IRConst.bool(true), // case nil => true
164
+ _ir_and(
165
+ // both predicate(head) is true
166
+ _ir_apps(new IRVar(every_pred), new IRApp(IRNative.headList, new IRVar(every_lst))),
167
+ // AND self(tail) is true
168
+ _ir_apps(new IRSelfCall(every_self), new IRApp(IRNative.tailList, new IRVar(every_lst)))))))));
158
169
  hoisted_every.hash;
159
170
  // hoisted _filter
160
171
  const filt_pred = Symbol("predicate");
@@ -249,6 +260,11 @@ export function nativeToIR(native) {
249
260
  case IRNativeTag._mkMapList: return hoisted_mkMapList.clone();
250
261
  case IRNativeTag._increment: return hoisted_addOne.clone();
251
262
  case IRNativeTag._decrement: return hoisted_subOne.clone();
263
+ // case IRNativeTag._bytesToIntBE: ;
264
+ // case IRNativeTag._equalBoolean: ;
265
+ // case IRNativeTag._equalPairData: ;
266
+ case IRNativeTag._mkEqualsList: return hoisted_mkEqualsList.clone();
267
+ case IRNativeTag._negateInt: return hoisted_negateInteger.clone();
252
268
  // case IRNativeTag._mkEqualsList: return hoisted_mkEqualsList.clone();
253
269
  default:
254
270
  throw new Error("unknown (negative) native calling 'nativeToIR'; " +
@@ -333,9 +333,15 @@ export class AstCompiler extends DiagnosticEmitter {
333
333
  if (!funcExpr)
334
334
  return undefined;
335
335
  this.program.functions.set(tirFuncName, funcExpr);
336
+ this.program.functions.set(astFuncName, funcExpr);
336
337
  if (topLevelScope.functions.has(astFuncName))
337
338
  return this.error(DiagnosticCode._0_is_already_defined, astFuncExpr.name.range, astFuncName);
338
339
  topLevelScope.functions.set(astFuncName, tirFuncName);
340
+ topLevelScope.defineValue({
341
+ isConstant: true,
342
+ name: astFuncName,
343
+ type: funcExpr.type,
344
+ });
339
345
  if (exportRange && srcExports) {
340
346
  if (srcExports.functions.has(astFuncName)
341
347
  || srcExports.variables.has(astFuncName))
@@ -32,6 +32,7 @@ import { StructConstrDecl, StructDecl, StructDeclAstFlags } from "../../../../as
32
32
  import { NamedDeconstructVarDecl } from "../../../../ast/nodes/statements/declarations/VarDecl/NamedDeconstructVarDecl.js";
33
33
  import { SimpleVarDecl } from "../../../../ast/nodes/statements/declarations/VarDecl/SimpleVarDecl.js";
34
34
  import { SingleDeconstructVarDecl } from "../../../../ast/nodes/statements/declarations/VarDecl/SingleDeconstructVarDecl.js";
35
+ import { isVarDecl } from "../../../../ast/nodes/statements/declarations/VarDecl/VarDecl.js";
35
36
  import { EmptyStmt } from "../../../../ast/nodes/statements/EmptyStmt.js";
36
37
  import { FailStmt } from "../../../../ast/nodes/statements/FailStmt.js";
37
38
  import { ForOfStmt } from "../../../../ast/nodes/statements/ForOfStmt.js";
@@ -379,7 +380,9 @@ renamedVariables = {}) {
379
380
  function _getMatchedRedeemerBlockStatements(compiler, stmts, paramsInternalNamesMap, contextVarsMapping, renamedVariables) {
380
381
  const result = stmts.slice();
381
382
  for (let i = 0; i < result.length; i++) {
382
- const stmt = result[i];
383
+ let stmt = result[i];
384
+ if (isVarDecl(stmt))
385
+ stmt = new VarStmt([stmt], stmt.range);
383
386
  if (stmt instanceof VarStmt) {
384
387
  if (stmt.declarations.length !== 1) {
385
388
  for (const varDecl of stmt.declarations) {
@@ -587,6 +590,7 @@ function _getMatchedRedeemerBlockStatements(compiler, stmts, paramsInternalNames
587
590
  continue;
588
591
  }
589
592
  const tsEnsureExhaustiveCheck = stmt;
593
+ console.error(stmt);
590
594
  throw new Error("unreachable::_getMatchedRedeemerBlockStatements::stmt::");
591
595
  }
592
596
  return result;
@@ -8,6 +8,7 @@ export declare class Compiler extends DiagnosticEmitter {
8
8
  constructor(io?: CompilerIoApi, cfg?: CompilerOptions, diagnostics?: DiagnosticMessage[]);
9
9
  compile(config?: Partial<CompilerOptions>): Promise<Uint8Array>;
10
10
  export(config: Partial<ExportOptions> & HasFuncitonName): Promise<Uint8Array>;
11
+ private _compileBackend;
11
12
  }
12
13
  interface HasFuncitonName {
13
14
  functionName: string;
@@ -34,16 +34,7 @@ export class Compiler extends DiagnosticEmitter {
34
34
  }
35
35
  throw new Error("compilation failed with " + nDiags + " diagnostic messages; first message: " + fstErrorMsg);
36
36
  }
37
- // backend starts here
38
- const ir = compileTypedProgram(cfg, program);
39
- const uplc = compileIRToUPLC(ir);
40
- const serialized = compileUPLC(new UPLCProgram(cfg.targetUplcVersion, uplc)).toBuffer().buffer;
41
- const outDir = cfg.outDir;
42
- const outPath = outDir + (outDir.endsWith("/") ? "" : "/") + "out.flat";
43
- this.io.writeFile(outPath, serialized, cfg.root);
44
- this.io.stdout.write(`compiled program written to ${outPath}\n`);
45
- __VERY_UNSAFE_FORGET_IRHASH_ONLY_USE_AT_END_OF_UPLC_COMPILATION();
46
- return serialized;
37
+ return this._compileBackend(cfg, program);
47
38
  }
48
39
  async export(config) {
49
40
  const cfg = {
@@ -67,6 +58,9 @@ export class Compiler extends DiagnosticEmitter {
67
58
  }
68
59
  throw new Error("compilation failed with " + nDiags + " diagnostic messages; first message: " + fstErrorMsg);
69
60
  }
61
+ return this._compileBackend(cfg, program);
62
+ }
63
+ _compileBackend(cfg, program) {
70
64
  // backend starts here
71
65
  const ir = compileTypedProgram(cfg, program);
72
66
  const uplc = compileIRToUPLC(ir, cfg);
@@ -51,12 +51,16 @@ export class ExpressifyCtx {
51
51
  this.properties = properties;
52
52
  this.hoisted = (hoisted
53
53
  ?? this.parent?.hoisted
54
- ?? new Map([...program.constants.entries()].map(([name, decl]) => {
54
+ ?? new Map([...program.constants.entries()]
55
+ .map(([name, decl]) => {
55
56
  if (!decl.initExpr)
56
57
  throw new Error(`expected init expr in hoisted constant '${name}'`);
57
58
  const expr = decl.initExpr instanceof TirHoistedExpr ? decl.initExpr : new TirHoistedExpr(name, decl.initExpr);
58
59
  return [name, expr];
59
- })));
60
+ })
61
+ .concat([...program.functions.entries()].map(([name, func]) => {
62
+ return [name, new TirHoistedExpr(name, func)];
63
+ }))));
60
64
  }
61
65
  allVariablesNoLetted() {
62
66
  return (this.parent?.allVariablesNoLetted() ?? []).concat(...this.variables.keys());
@@ -119,7 +123,7 @@ export class ExpressifyCtx {
119
123
  const result = (this._getNonHoistedVariable(name)
120
124
  ?? this.hoisted.get(name));
121
125
  if (!result) {
122
- console.log("[error log]: allVariables", this.allVariables());
126
+ console.log("[error log]: allVariables", this.allVariables(), "; get:", name);
123
127
  throw new Error(`variable '${name}' not found in the context`);
124
128
  }
125
129
  return result;
@@ -72,6 +72,7 @@ import { Precedence, determinePrecedence } from "./Precedence.js";
72
72
  import { LitFailExpr } from "../ast/nodes/expr/litteral/LitFailExpr.js";
73
73
  import { ContractDecl } from "../ast/nodes/statements/declarations/ContractDecl.js";
74
74
  import { LitContextExpr } from "../ast/nodes/expr/litteral/LitContextExpr.js";
75
+ import { tokenIsAlsoIdentifier } from "../tokenizer/utils/tokenIsAlsoIdentifier.js";
75
76
  export class Parser extends DiagnosticEmitter {
76
77
  tn;
77
78
  constructor(tokenizer, diagnostics = undefined) {
@@ -833,6 +834,12 @@ export class Parser extends DiagnosticEmitter {
833
834
  _parseVarDecl(flags, skipTypeAndInitializer = false) {
834
835
  const tn = this.tn;
835
836
  // ConstrName{ ... } || renamed
837
+ const identifierToken = tn.peek();
838
+ if (identifierToken !== Token.Identifier
839
+ && identifierToken !== Token.OpenBrace // valid var destructuring (single constr obj)
840
+ && identifierToken !== Token.OpenBracket // valid var destructuring (array-like)
841
+ && !tokenIsAlsoIdentifier(identifierToken))
842
+ return this.error(DiagnosticCode._0_keyword_cannot_be_used_here, tn.range(tn.nextTokenPos, tn.nextToken), Token[identifierToken]);
836
843
  const renamedField = this.parseIdentifier();
837
844
  if (tn.skip(Token.OpenBrace)) // ConstrName{ ... } || { ... }
838
845
  {
@@ -1,3 +1,5 @@
1
1
  import type { Source } from "../ast/Source/Source.js";
2
- export declare function parseFile(path: string, src: string, getUid?: () => string, isEntry?: boolean): [Source, import("../diagnostics/DiagnosticMessage.js").DiagnosticMessage[]];
3
- export declare function parseSource(src: Source): import("../diagnostics/DiagnosticMessage.js").DiagnosticMessage[];
2
+ import { DiagnosticMessage } from "../diagnostics/DiagnosticMessage.js";
3
+ export declare function parseFilePure(path: string, src: string, getUid?: () => string, isEntry?: boolean): [Source, DiagnosticMessage[]];
4
+ export declare function parseFile(path: string, src: string, getUid?: () => string, isEntry?: boolean): Source;
5
+ export declare function parseSource(src: Source): DiagnosticMessage[];
@@ -1,8 +1,15 @@
1
1
  import { defaultSymbolForge } from "../compiler/internalVar.js";
2
2
  import { Parser } from "./Parser.js";
3
- export function parseFile(path, src, getUid = defaultSymbolForge.getUid.bind(defaultSymbolForge), isEntry = false) {
3
+ export function parseFilePure(path, src, getUid = defaultSymbolForge.getUid.bind(defaultSymbolForge), isEntry = false) {
4
4
  return Parser.parseFile(path, src, getUid, isEntry);
5
5
  }
6
+ export function parseFile(path, src, getUid = defaultSymbolForge.getUid.bind(defaultSymbolForge), isEntry = false) {
7
+ const [source, diagnostics] = Parser.parseFile(path, src, getUid, isEntry);
8
+ if (diagnostics.length > 0) {
9
+ throw new Error(`Parsing errors:\n${diagnostics.map(d => d.toString()).join("\n")}`);
10
+ }
11
+ return source;
12
+ }
6
13
  export function parseSource(src) {
7
14
  return Parser.parseSource(src);
8
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harmoniclabs/pebble",
3
- "version": "0.1.2",
3
+ "version": "0.1.3-dev0",
4
4
  "description": "A simple, yet rock solid, functional language with an imperative bias, targeting UPLC",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",