@@ -41,39 +41,53 @@ export function executeScriptOnVM(script: Script): Uint8Array[] {
4141 return res . stack ;
4242}
4343
44- export function applyUnaryOperator (
45- op : UnaryOperator ,
46- expr : LiteralNode ,
47- ) : LiteralNode {
48- if ( expr instanceof BoolLiteralNode ) {
49- return applyUnaryOperatorToBool ( op , expr ) ;
50- } else if ( expr instanceof IntLiteralNode ) {
51- return applyUnaryOperatorToInt ( op , expr ) ;
52- } else {
53- throw new Error ( ) ; // Already checked in typecheck
44+ // TODO: RequireNode
45+ // TODO: BranchNode
46+ // TODO: CastNode
47+
48+ export function applyGlobalFunction ( node : FunctionCallNode ) : Node {
49+ const { parameters } = node ;
50+ const fn = node . identifier . name as GlobalFunction ;
51+
52+ // TODO: Apply checkMultiSig (requires code generation refactor)
53+ // This is not very important, since checkMultiSig likely requires external args
54+ if ( fn === GlobalFunction . CHECKMULTISIG ) {
55+ return node ;
5456 }
55- }
5657
57- function applyUnaryOperatorToBool (
58- op : UnaryOperator ,
59- expr : BoolLiteralNode ,
60- ) : BoolLiteralNode {
61- const script : Script = ( [ Data . encodeBool ( expr . value ) ] as Script )
62- . concat ( toOps . fromUnaryOp ( op ) ) ;
63- const res = executeScriptOnVM ( script ) [ 0 ] ;
64- return new BoolLiteralNode ( Data . decodeBool ( Buffer . from ( res ) ) ) ;
65- }
58+ let script : Script = parameters . map ( ( p ) => {
59+ if ( p instanceof BoolLiteralNode ) {
60+ return Data . encodeBool ( p . value ) ;
61+ } else if ( p instanceof IntLiteralNode ) {
62+ return Data . encodeInt ( p . value ) ;
63+ } else if ( p instanceof StringLiteralNode ) {
64+ return Data . encodeString ( p . value ) ;
65+ } else if ( p instanceof HexLiteralNode ) {
66+ return p . value ;
67+ } else {
68+ throw new Error ( ) ; // Already checked in typecheck
69+ }
70+ } ) ;
71+ script = script . concat ( toOps . fromFunction ( node . identifier . name as GlobalFunction ) ) ;
6672
67- function applyUnaryOperatorToInt (
68- op : UnaryOperator ,
69- expr : IntLiteralNode ,
70- ) : IntLiteralNode {
71- const script : Script = ( [ Data . encodeInt ( expr . value ) ] as Script )
72- . concat ( toOps . fromUnaryOp ( op ) ) ;
7373 const res = executeScriptOnVM ( script ) [ 0 ] ;
74- return new IntLiteralNode ( Data . decodeInt ( Buffer . from ( res ) ) ) ;
74+ if ( returnType ( fn ) === PrimitiveType . BOOL ) {
75+ return new BoolLiteralNode ( Data . decodeBool ( Buffer . from ( res ) ) ) ;
76+ } else if ( returnType ( fn ) === PrimitiveType . INT ) {
77+ return new IntLiteralNode ( Data . decodeInt ( Buffer . from ( res ) ) ) ;
78+ } else if ( returnType ( fn ) === PrimitiveType . STRING ) {
79+ return new StringLiteralNode ( Data . decodeString ( Buffer . from ( res ) ) , '"' ) ;
80+ } else if ( returnType ( fn ) instanceof BytesType ) {
81+ return new HexLiteralNode ( Buffer . from ( res ) ) ;
82+ } else {
83+ throw new Error ( ) ; // Already checked in typecheck
84+ }
7585}
7686
87+ // TODO: InstantiationNode
88+ // TODO: TupleIndexOpNode + SplitOpNode
89+ // TODO: SizeOpNode
90+
7791export function applyBinaryOperator (
7892 left : LiteralNode ,
7993 op : BinaryOperator ,
@@ -142,40 +156,35 @@ function applyBinaryOperatorToHex(
142156 : new HexLiteralNode ( Buffer . from ( res ) ) ;
143157}
144158
145- export function applyGlobalFunction ( node : FunctionCallNode ) : Node {
146- const { parameters } = node ;
147- const fn = node . identifier . name as GlobalFunction ;
148-
149- // Don't apply checkMultiSig or require for now
150- if ( fn === GlobalFunction . CHECKMULTISIG || fn === GlobalFunction . REQUIRE ) {
151- return node ;
159+ export function applyUnaryOperator (
160+ op : UnaryOperator ,
161+ expr : LiteralNode ,
162+ ) : LiteralNode {
163+ if ( expr instanceof BoolLiteralNode ) {
164+ return applyUnaryOperatorToBool ( op , expr ) ;
165+ } else if ( expr instanceof IntLiteralNode ) {
166+ return applyUnaryOperatorToInt ( op , expr ) ;
167+ } else {
168+ throw new Error ( ) ; // Already checked in typecheck
152169 }
170+ }
153171
154- let script : Script = parameters . map ( ( p ) => {
155- if ( p instanceof BoolLiteralNode ) {
156- return Data . encodeBool ( p . value ) ;
157- } else if ( p instanceof IntLiteralNode ) {
158- return Data . encodeInt ( p . value ) ;
159- } else if ( p instanceof StringLiteralNode ) {
160- return Data . encodeString ( p . value ) ;
161- } else if ( p instanceof HexLiteralNode ) {
162- return p . value ;
163- } else {
164- throw new Error ( ) ; // Already checked in typecheck
165- }
166- } ) ;
167- script = script . concat ( toOps . fromFunction ( node . identifier . name as GlobalFunction ) ) ;
172+ function applyUnaryOperatorToBool (
173+ op : UnaryOperator ,
174+ expr : BoolLiteralNode ,
175+ ) : BoolLiteralNode {
176+ const script : Script = ( [ Data . encodeBool ( expr . value ) ] as Script )
177+ . concat ( toOps . fromUnaryOp ( op ) ) ;
178+ const res = executeScriptOnVM ( script ) [ 0 ] ;
179+ return new BoolLiteralNode ( Data . decodeBool ( Buffer . from ( res ) ) ) ;
180+ }
168181
182+ function applyUnaryOperatorToInt (
183+ op : UnaryOperator ,
184+ expr : IntLiteralNode ,
185+ ) : IntLiteralNode {
186+ const script : Script = ( [ Data . encodeInt ( expr . value ) ] as Script )
187+ . concat ( toOps . fromUnaryOp ( op ) ) ;
169188 const res = executeScriptOnVM ( script ) [ 0 ] ;
170- if ( returnType ( fn ) === PrimitiveType . BOOL ) {
171- return new BoolLiteralNode ( Data . decodeBool ( Buffer . from ( res ) ) ) ;
172- } else if ( returnType ( fn ) === PrimitiveType . INT ) {
173- return new IntLiteralNode ( Data . decodeInt ( Buffer . from ( res ) ) ) ;
174- } else if ( returnType ( fn ) === PrimitiveType . STRING ) {
175- return new StringLiteralNode ( Data . decodeString ( Buffer . from ( res ) ) , '"' ) ;
176- } else if ( returnType ( fn ) instanceof BytesType ) {
177- return new HexLiteralNode ( Buffer . from ( res ) ) ;
178- } else {
179- throw new Error ( ) ; // Already checked in typecheck
180- }
189+ return new IntLiteralNode ( Data . decodeInt ( Buffer . from ( res ) ) ) ;
181190}
0 commit comments