cashc 0.9.2 → 0.10.0-next.0

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.
@@ -1,3 +1,9 @@
1
- import { Artifact, Script } from '@cashscript/utils';
1
+ import { Artifact, LogEntry, RequireMessage, Script } from '@cashscript/utils';
2
2
  import { Ast } from '../ast/AST.js';
3
- export declare function generateArtifact(ast: Ast, script: Script, source: string): Artifact;
3
+ export declare function generateArtifact(ast: Ast, script: Script, source: string, debug: {
4
+ script: Script;
5
+ sourceMap: string;
6
+ logs: LogEntry[];
7
+ requireMessages: RequireMessage[];
8
+ }): Artifact;
9
+ export declare function stripArtifact(artifact: Artifact): Omit<Artifact, 'debug'>;
@@ -1,6 +1,7 @@
1
- import { scriptToAsm } from '@cashscript/utils';
1
+ import { scriptToAsm, scriptToBytecode, } from '@cashscript/utils';
2
2
  import { version } from '../index.js';
3
- export function generateArtifact(ast, script, source) {
3
+ import { binToHex } from '@bitauth/libauth';
4
+ export function generateArtifact(ast, script, source, debug) {
4
5
  const { contract } = ast;
5
6
  const constructorInputs = contract.parameters
6
7
  .map((parameter) => ({ name: parameter.name, type: parameter.type.toString() }));
@@ -12,12 +13,19 @@ export function generateArtifact(ast, script, source) {
12
13
  })),
13
14
  }));
14
15
  const bytecode = scriptToAsm(script);
16
+ const debugBytecode = binToHex(scriptToBytecode(debug.script));
15
17
  return {
16
18
  contractName: contract.name,
17
19
  constructorInputs,
18
20
  abi,
19
21
  bytecode,
20
22
  source,
23
+ debug: {
24
+ bytecode: debugBytecode,
25
+ sourceMap: debug.sourceMap,
26
+ logs: debug.logs,
27
+ requireMessages: debug.requireMessages,
28
+ },
21
29
  compiler: {
22
30
  name: 'cashc',
23
31
  version,
@@ -25,4 +33,9 @@ export function generateArtifact(ast, script, source) {
25
33
  updatedAt: new Date().toISOString(),
26
34
  };
27
35
  }
36
+ // strip verbose debug info from artifact for production use
37
+ export function stripArtifact(artifact) {
38
+ delete artifact.debug;
39
+ return artifact;
40
+ }
28
41
  //# sourceMappingURL=Artifact.js.map
package/dist/ast/AST.d.ts CHANGED
@@ -81,12 +81,14 @@ export declare class AssignNode extends StatementNode {
81
81
  export declare class TimeOpNode extends StatementNode {
82
82
  timeOp: TimeOp;
83
83
  expression: ExpressionNode;
84
- constructor(timeOp: TimeOp, expression: ExpressionNode);
84
+ message?: string | undefined;
85
+ constructor(timeOp: TimeOp, expression: ExpressionNode, message?: string | undefined);
85
86
  accept<T>(visitor: AstVisitor<T>): T;
86
87
  }
87
88
  export declare class RequireNode extends StatementNode {
88
89
  expression: ExpressionNode;
89
- constructor(expression: ExpressionNode);
90
+ message?: string | undefined;
91
+ constructor(expression: ExpressionNode, message?: string | undefined);
90
92
  accept<T>(visitor: AstVisitor<T>): T;
91
93
  }
92
94
  export declare class BranchNode extends StatementNode {
@@ -182,3 +184,14 @@ export declare class HexLiteralNode extends LiteralNode {
182
184
  constructor(value: Uint8Array);
183
185
  accept<T>(visitor: AstVisitor<T>): T;
184
186
  }
187
+ export declare class ConsoleStatementNode extends Node {
188
+ parameters: ConsoleParameterNode[];
189
+ constructor(parameters: ConsoleParameterNode[]);
190
+ accept<T>(visitor: AstVisitor<T>): T;
191
+ }
192
+ export declare class ConsoleParameterNode extends Node {
193
+ message?: string | undefined;
194
+ identifier?: string | undefined;
195
+ constructor(message?: string | undefined, identifier?: string | undefined);
196
+ accept<T>(visitor: AstVisitor<T>): T;
197
+ }
package/dist/ast/AST.js CHANGED
@@ -79,19 +79,21 @@ export class AssignNode extends StatementNode {
79
79
  }
80
80
  }
81
81
  export class TimeOpNode extends StatementNode {
82
- constructor(timeOp, expression) {
82
+ constructor(timeOp, expression, message) {
83
83
  super();
84
84
  this.timeOp = timeOp;
85
85
  this.expression = expression;
86
+ this.message = message;
86
87
  }
87
88
  accept(visitor) {
88
89
  return visitor.visitTimeOp(this);
89
90
  }
90
91
  }
91
92
  export class RequireNode extends StatementNode {
92
- constructor(expression) {
93
+ constructor(expression, message) {
93
94
  super();
94
95
  this.expression = expression;
96
+ this.message = message;
95
97
  }
96
98
  accept(visitor) {
97
99
  return visitor.visitRequire(this);
@@ -251,4 +253,23 @@ export class HexLiteralNode extends LiteralNode {
251
253
  return visitor.visitHexLiteral(this);
252
254
  }
253
255
  }
256
+ export class ConsoleStatementNode extends Node {
257
+ constructor(parameters) {
258
+ super();
259
+ this.parameters = parameters;
260
+ }
261
+ accept(visitor) {
262
+ return visitor.visitConsoleStatement(this);
263
+ }
264
+ }
265
+ export class ConsoleParameterNode extends Node {
266
+ constructor(message, identifier) {
267
+ super();
268
+ this.message = message;
269
+ this.identifier = identifier;
270
+ }
271
+ accept(visitor) {
272
+ return visitor.visitConsoleParameter(this);
273
+ }
274
+ }
254
275
  //# sourceMappingURL=AST.js.map
@@ -1,7 +1,7 @@
1
1
  import { AbstractParseTreeVisitor } from 'antlr4ts/tree/AbstractParseTreeVisitor.js';
2
2
  import { ParseTree } from 'antlr4ts/tree/ParseTree.js';
3
- import { Node, SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, ExpressionNode, LiteralNode, BlockNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode } from './AST.js';
4
- import type { ContractDefinitionContext, FunctionDefinitionContext, VariableDefinitionContext, TupleAssignmentContext, ParameterContext, AssignStatementContext, IfStatementContext, FunctionCallContext, CastContext, LiteralContext, SourceFileContext, BlockContext, TimeOpStatementContext, ArrayContext, ParenthesisedContext, FunctionCallExpressionContext, UnaryOpContext, BinaryOpContext, IdentifierContext, LiteralExpressionContext, TupleIndexOpContext, RequireStatementContext, PragmaDirectiveContext, InstantiationContext, NullaryOpContext, UnaryIntrospectionOpContext } from '../grammar/CashScriptParser.js';
3
+ import { Node, SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, ExpressionNode, LiteralNode, BlockNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode, ConsoleParameterNode } from './AST.js';
4
+ import type { ContractDefinitionContext, FunctionDefinitionContext, VariableDefinitionContext, TupleAssignmentContext, ParameterContext, AssignStatementContext, IfStatementContext, FunctionCallContext, CastContext, LiteralContext, SourceFileContext, BlockContext, TimeOpStatementContext, ArrayContext, ParenthesisedContext, FunctionCallExpressionContext, UnaryOpContext, BinaryOpContext, IdentifierContext, LiteralExpressionContext, TupleIndexOpContext, RequireStatementContext, PragmaDirectiveContext, InstantiationContext, NullaryOpContext, UnaryIntrospectionOpContext, ConsoleStatementContext, ConsoleParameterContext } from '../grammar/CashScriptParser.js';
5
5
  import type { CashScriptVisitor } from '../grammar/CashScriptVisitor.js';
6
6
  export default class AstBuilder extends AbstractParseTreeVisitor<Node> implements CashScriptVisitor<Node> {
7
7
  private tree;
@@ -39,4 +39,6 @@ export default class AstBuilder extends AbstractParseTreeVisitor<Node> implement
39
39
  createStringLiteral(ctx: LiteralContext): StringLiteralNode;
40
40
  createDateLiteral(ctx: LiteralContext): IntLiteralNode;
41
41
  createHexLiteral(ctx: LiteralContext): HexLiteralNode;
42
+ visitConsoleStatement(ctx: ConsoleStatementContext): ConsoleStatementNode;
43
+ visitConsoleParameter(ctx: ConsoleParameterContext): ConsoleParameterNode;
42
44
  }
@@ -2,7 +2,7 @@ import { hexToBin } from '@bitauth/libauth';
2
2
  import { parseType } from '@cashscript/utils';
3
3
  import { AbstractParseTreeVisitor } from 'antlr4ts/tree/AbstractParseTreeVisitor.js';
4
4
  import semver from 'semver';
5
- import { SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, BlockNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, } from './AST.js';
5
+ import { SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, BlockNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode, ConsoleParameterNode, } from './AST.js';
6
6
  import { Location } from './Location.js';
7
7
  import { NumberUnit, } from './Globals.js';
8
8
  import { getPragmaName, PragmaName, getVersionOpFromCtx } from './Pragma.js';
@@ -95,13 +95,15 @@ export default class AstBuilder extends AbstractParseTreeVisitor {
95
95
  }
96
96
  visitTimeOpStatement(ctx) {
97
97
  const expression = this.visit(ctx.expression());
98
- const timeOp = new TimeOpNode(ctx.TxVar().text, expression);
98
+ const message = ctx.StringLiteral() && this.createStringLiteral(ctx)?.value;
99
+ const timeOp = new TimeOpNode(ctx.TxVar().text, expression, message);
99
100
  timeOp.location = Location.fromCtx(ctx);
100
101
  return timeOp;
101
102
  }
102
103
  visitRequireStatement(ctx) {
103
104
  const expression = this.visit(ctx.expression());
104
- const require = new RequireNode(expression);
105
+ const message = ctx.StringLiteral() && this.createStringLiteral(ctx)?.value;
106
+ const require = new RequireNode(expression, message);
105
107
  require.location = Location.fromCtx(ctx);
106
108
  return require;
107
109
  }
@@ -261,5 +263,21 @@ export default class AstBuilder extends AbstractParseTreeVisitor {
261
263
  hexLiteral.location = Location.fromCtx(ctx);
262
264
  return hexLiteral;
263
265
  }
266
+ visitConsoleStatement(ctx) {
267
+ const parameters = ctx.consoleParameterList().consoleParameter().map((p) => this.visit(p));
268
+ const node = new ConsoleStatementNode(parameters);
269
+ node.location = Location.fromCtx(ctx);
270
+ return node;
271
+ }
272
+ visitConsoleParameter(ctx) {
273
+ let message = (ctx.BooleanLiteral() ?? ctx.HexLiteral() ?? ctx.NumberLiteral() ?? ctx.StringLiteral())?.text;
274
+ if (message?.[0] === '"') {
275
+ message = message.slice(1, -1);
276
+ }
277
+ const identifier = ctx.Identifier()?.text;
278
+ const node = new ConsoleParameterNode(message, identifier);
279
+ node.location = Location.fromCtx(ctx);
280
+ return node;
281
+ }
264
282
  }
265
283
  //# sourceMappingURL=AstBuilder.js.map
@@ -1,4 +1,4 @@
1
- import { Node, SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, BlockNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode } from './AST.js';
1
+ import { Node, SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, BlockNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode, ConsoleParameterNode } from './AST.js';
2
2
  import AstVisitor from './AstVisitor.js';
3
3
  export default class AstTraversal extends AstVisitor<Node> {
4
4
  visitSourceFile(node: SourceFileNode): Node;
@@ -25,4 +25,6 @@ export default class AstTraversal extends AstVisitor<Node> {
25
25
  visitIntLiteral(node: IntLiteralNode): Node;
26
26
  visitStringLiteral(node: StringLiteralNode): Node;
27
27
  visitHexLiteral(node: HexLiteralNode): Node;
28
+ visitConsoleStatement(node: ConsoleStatementNode): Node;
29
+ visitConsoleParameter(node: ConsoleParameterNode): Node;
28
30
  }
@@ -98,5 +98,12 @@ export default class AstTraversal extends AstVisitor {
98
98
  visitHexLiteral(node) {
99
99
  return node;
100
100
  }
101
+ visitConsoleStatement(node) {
102
+ node.parameters = this.visitList(node.parameters);
103
+ return node;
104
+ }
105
+ visitConsoleParameter(node) {
106
+ return node;
107
+ }
101
108
  }
102
109
  //# sourceMappingURL=AstTraversal.js.map
@@ -1,4 +1,4 @@
1
- import { Node, SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, BlockNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode } from './AST.js';
1
+ import { Node, SourceFileNode, ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, BlockNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode, ConsoleParameterNode } from './AST.js';
2
2
  export default abstract class AstVisitor<T> {
3
3
  abstract visitSourceFile(node: SourceFileNode): T;
4
4
  abstract visitContract(node: ContractNode): T;
@@ -24,6 +24,8 @@ export default abstract class AstVisitor<T> {
24
24
  abstract visitIntLiteral(node: IntLiteralNode): T;
25
25
  abstract visitStringLiteral(node: StringLiteralNode): T;
26
26
  abstract visitHexLiteral(node: HexLiteralNode): T;
27
+ abstract visitConsoleStatement(node: ConsoleStatementNode): T;
28
+ abstract visitConsoleParameter(node: ConsoleParameterNode): T;
27
29
  visit(node: Node): T;
28
30
  visitOptional(node?: Node): T | undefined;
29
31
  visitList(nodes: Node[]): T[];
@@ -1,11 +1,13 @@
1
1
  import type { ParserRuleContext } from 'antlr4ts/ParserRuleContext.js';
2
2
  import type { Token } from 'antlr4ts';
3
- export declare class Location {
3
+ import { LocationI } from '@cashscript/utils';
4
+ export declare class Location implements LocationI {
4
5
  start: Point;
5
6
  end: Point;
6
7
  constructor(start: Point, end: Point);
7
8
  static fromCtx(ctx: ParserRuleContext): Location | undefined;
8
9
  static fromToken(token: Token): Location | undefined;
10
+ static fromObject(object: LocationI): Location;
9
11
  text(code: string): string;
10
12
  }
11
13
  export declare class Point {
@@ -16,6 +16,11 @@ export class Location {
16
16
  const end = new Point(token.line, token.charPositionInLine + textLength);
17
17
  return new Location(start, end);
18
18
  }
19
+ static fromObject(object) {
20
+ const start = new Point(object.start.line, object.start.column);
21
+ const end = new Point(object.end.line, object.end.column);
22
+ return new Location(start, end);
23
+ }
19
24
  text(code) {
20
25
  return code.slice(this.start.offset(code), this.end.offset(code));
21
26
  }
package/dist/compiler.js CHANGED
@@ -14,16 +14,21 @@ export function compileString(code) {
14
14
  // Lexing + parsing
15
15
  let ast = parseCode(code);
16
16
  // Semantic analysis
17
- ast = ast.accept(new SymbolTableTraversal());
17
+ const symbolTableTraversal = new SymbolTableTraversal();
18
+ ast = ast.accept(symbolTableTraversal);
18
19
  ast = ast.accept(new TypeCheckTraversal());
19
20
  ast = ast.accept(new EnsureFinalRequireTraversal());
20
21
  // Code generation
21
- const traversal = new GenerateTargetTraversal();
22
+ const traversal = new GenerateTargetTraversal(symbolTableTraversal.logSymbols);
22
23
  ast = ast.accept(traversal);
23
- const bytecode = traversal.output;
24
24
  // Bytecode optimisation
25
- const optimisedBytecode = optimiseBytecode(bytecode);
26
- return generateArtifact(ast, optimisedBytecode, code);
25
+ const optimisedBytecode = optimiseBytecode(traversal.output);
26
+ return generateArtifact(ast, optimisedBytecode, code, {
27
+ script: traversal.output,
28
+ sourceMap: traversal.souceMap,
29
+ logs: traversal.consoleLogs,
30
+ requireMessages: traversal.requireMessages,
31
+ });
27
32
  }
28
33
  export function compileFile(codeFile) {
29
34
  const code = fs.readFileSync(codeFile, { encoding: 'utf-8' });
@@ -1,11 +1,19 @@
1
- import { Script } from '@cashscript/utils';
2
- import { ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, SourceFileNode, Node, InstantiationNode, TupleAssignmentNode, NullaryOpNode } from '../ast/AST.js';
1
+ import { Script, LogEntry, RequireMessage } from '@cashscript/utils';
2
+ import { ContractNode, ParameterNode, VariableDefinitionNode, FunctionDefinitionNode, AssignNode, IdentifierNode, BranchNode, CastNode, FunctionCallNode, UnaryOpNode, BinaryOpNode, BoolLiteralNode, IntLiteralNode, HexLiteralNode, StringLiteralNode, TimeOpNode, ArrayNode, TupleIndexOpNode, RequireNode, SourceFileNode, Node, InstantiationNode, TupleAssignmentNode, NullaryOpNode, ConsoleStatementNode } from '../ast/AST.js';
3
3
  import AstTraversal from '../ast/AstTraversal.js';
4
- export default class GenerateTargetTraversal extends AstTraversal {
4
+ import { Symbol } from '../ast/SymbolTable.js';
5
+ export default class GenerateTargetTraversalWithLocation extends AstTraversal {
6
+ private logSymbols;
7
+ private locationData;
8
+ souceMap: string;
5
9
  output: Script;
6
10
  stack: string[];
11
+ consoleLogs: LogEntry[];
12
+ requireMessages: RequireMessage[];
7
13
  private scopeDepth;
8
14
  private currentFunction;
15
+ private constructorParameterCount;
16
+ constructor(logSymbols: Symbol[]);
9
17
  private emit;
10
18
  private pushToStack;
11
19
  private popFromStack;
@@ -15,17 +23,17 @@ export default class GenerateTargetTraversal extends AstTraversal {
15
23
  visitSourceFile(node: SourceFileNode): Node;
16
24
  visitContract(node: ContractNode): Node;
17
25
  visitFunctionDefinition(node: FunctionDefinitionNode): Node;
18
- removeFinalVerify(): void;
19
- cleanStack(): void;
26
+ removeFinalVerify(node: Node): void;
27
+ cleanStack(node: Node): void;
20
28
  visitParameter(node: ParameterNode): Node;
21
29
  visitVariableDefinition(node: VariableDefinitionNode): Node;
22
30
  visitTupleAssignment(node: TupleAssignmentNode): Node;
23
31
  visitAssign(node: AssignNode): Node;
24
- emitReplace(index: number): void;
32
+ emitReplace(index: number, node: Node): void;
25
33
  visitTimeOp(node: TimeOpNode): Node;
26
34
  visitRequire(node: RequireNode): Node;
27
35
  visitBranch(node: BranchNode): Node;
28
- removeScopedVariables(depthBeforeScope: number): void;
36
+ removeScopedVariables(depthBeforeScope: number, node: Node): void;
29
37
  visitCast(node: CastNode): Node;
30
38
  visitFunctionCall(node: FunctionCallNode): Node;
31
39
  visitMultiSig(node: FunctionCallNode): Node;
@@ -41,4 +49,5 @@ export default class GenerateTargetTraversal extends AstTraversal {
41
49
  visitIntLiteral(node: IntLiteralNode): Node;
42
50
  visitStringLiteral(node: StringLiteralNode): Node;
43
51
  visitHexLiteral(node: HexLiteralNode): Node;
52
+ visitConsoleStatement(node: ConsoleStatementNode): Node;
44
53
  }