UNPKG

@webqit/quantum-js

Version:

Runtime extension to JavaScript that let's us do Imperative Reactive Programming (IRP) in the very language.

111 lines (101 loc) 7.2 kB
export default { // Statements & Clauses throwStmt( argument ) { return { type: 'ThrowStatement', argument }; }, tryStmt( block, handler, finalizer, guardedHandlers ) { return { type: 'TryStatement', block, handler, finalizer, guardedHandlers }; }, catchClause( param, body ) { return { type: 'CatchClause', param, body }; }, exprStmt( expression ) { return { type: 'ExpressionStatement', expression, }; }, blockStmt( body ) { return { type: 'BlockStatement', body }; }, labeledStmt( label, body ) { return { type: 'LabeledStatement', label, body }; }, withStmt( object, body ) { return { type: 'WithStatement', object, body }; }, ifStmt( test, consequent, alternate ) { return this.conditionalExpr(test, consequent, alternate, 'IfStatement'); }, switchStmt( discriminant, cases, lexical = false ) { return { type: 'SwitchStatement', discriminant, cases, /*lexical*/ /* Failing tests and seems to be SpiderMonkey-specific*/ }; }, switchCase( test, consequent ) { return { type: 'SwitchCase', test, consequent }; }, whileStmt( test, body ) { return { type: 'WhileStatement', test, body }; }, doWhileStmt( test, body ) { return { type: 'DoWhileStatement', test, body }; }, forStmt( init, test, update, body ) { return { type: 'ForStatement', init, test, update, body }; }, forInStmt( left, right, body ) { return { type: 'ForInStatement', left, right, body }; }, forOfStmt( left, right, body ) { return { type: 'ForOfStatement', left, right, body }; }, breakStmt( label = null ) { return { type: 'BreakStatement', label }; }, continueStmt( label = null ) { return { type: 'ContinueStatement', label }; }, returnStmt( argument ) { return { type: 'ReturnStatement', argument }; }, yieldExpr( argument, delegate = false ) { return { type: 'YieldExpression', argument, delegate }; }, awaitExpr( argument ) { return { type: 'AwaitExpression', argument }; }, // Declarations varDeclaration( kind, declarations ) { return { type: 'VariableDeclaration', kind, declarations } }, varDeclarator( id, init = null ) { return { type: 'VariableDeclarator', id, init } }, funcDeclaration( id, params, body, async = false, expression = false, generator = false ) { return this.func( 'FunctionDeclaration', ...arguments ); }, // Expressions sequenceExpr( expressions ) { return { type: 'SequenceExpression', expressions }; }, parensExpr( expression ) { return { type: 'ParenthesizedExpression', expression }; }, logicalExpr( operator, left, right ) { return { type: 'LogicalExpression', operator, left, right, }; }, binaryExpr( operator, left, right ) { return { type: 'BinaryExpression', operator, left, right, }; }, unaryExpr( operator, argument, prefix = true ) { return { type: 'UnaryExpression', operator, argument, prefix }; }, updateExpr( operator, argument, prefix = false ) { return { type: 'UpdateExpression', operator, argument, prefix }; }, assignmentExpr( left, right, operator = '=' ) { return { type: 'AssignmentExpression', operator, left, right }; }, assignmentPattern( left, right ) { return { type: 'AssignmentPattern', left, right }; }, thisExpr() { return { type: 'ThisExpression' }; }, conditionalExpr( test, consequent, alternate, type = 'ConditionalExpression' ) { return { type, test, consequent, alternate }; }, arrayExpr( elements ) { return { type: 'ArrayExpression', elements }; }, arrayPattern( elements ) { return { type: 'ArrayPattern', elements }; }, objectExpr( properties ) { return { type: 'ObjectExpression', properties }; }, objectPattern( properties ) { return { type: 'ObjectPattern', properties }; }, chainExpr( expression ) { return { type: 'ChainExpression', expression }; }, callExpr( callee, args, optional = false ) { return { type: 'CallExpression', callee, arguments: args, optional }; }, newExpr( callee, args ) { return { type: 'NewExpression', callee, arguments: args }; }, taggedTemplateExpr( tag, quasi ) { return { type: 'TaggedTemplateExpression', tag, quasi }; }, memberExpr( object, property, computed = false, optional = false ) { return { type: 'MemberExpression', object, property, computed, optional }; }, funcExpr( id, params, body, async = false, expression = false, generator = false ) { return this.func( 'FunctionExpression', ...arguments ); }, arrowFuncExpr( id, params, body, async = false, expression = false, generator = false ) { return this.func( 'ArrowFunctionExpression', ...arguments ); }, // Other func( type, id, params, body, async = false, expression = false, generator = false ) { return { type, id, params, body, async, expression, generator, }; }, identifier( name ) { return { type: 'Identifier', name }; }, property( key, value, kind = 'init', shorthand = false, computed = false, method = false ) { return { type: 'Property', key, value, kind, shorthand, computed, method }; }, classDeclaration( id, body, superClass = null ) { return this.class( 'ClassDeclaration', ...arguments ); }, classExpression( id, body, superClass = null ) { return this.class( 'ClassExpression', ...arguments ); }, class( type, id, body, superClass = null ) { return { type, id, body, superClass }; }, methodDefinition( key, value, kind = 'method', $static = false, computed = false ) { return { type: 'MethodDefinition', key, value, kind, static: $static, computed }; }, propertyDefinition( key, value, $static = false, computed = false ) { return { type: 'PropertyDefinition', key, value, static: $static, computed }; }, spreadElement( argument ) { return { type: 'SpreadElement', argument }; }, literal( value ) { if ( typeof value === 'object' && !( 'name' in value ) && !( 'value' in value ) ) throw new Error( `Objects that convert to literals must have a "name" or "value" property.` ); return typeof value === 'object' ? { type: 'Literal', get value() { return 'name' in value ? value.name : value.value } } : { type: 'Literal', value }; }, templateLiteral( quasis, expressions ) { return { type: 'TemplateLiteral', quasis, expressions }; }, comments( comments ) { const valueObject = {}; Object.defineProperty( valueObject, 'toString', { value: () => comments } ); Object.defineProperty( valueObject, 'trim', { value: function() { return this.toString(); } } ); return [ { type: 'Line', value: valueObject, } ]; }, withLoc( target, ...sources ) { [ 'start', 'end' ].forEach( offset => { const sourceNode = offset === 'start' ? sources[ 0 ] : sources[ sources.length - 1 ]; target[ offset ] = sourceNode[ offset ]; if ( sourceNode.loc ) { target.loc = target.loc || {}; target.loc[ offset ] = sourceNode.loc?.[ offset ]; } } ); return target; }, // Util invert( expr ) { return this.unaryExpr( '!', expr ); }, clone( expr ) { expr = { ...expr }; delete expr.start; delete expr.end; return expr; }, }