Skip to content
This repository has been archived by the owner on Sep 22, 2020. It is now read-only.

Commit

Permalink
Added MakeNode and MockParser
Browse files Browse the repository at this point in the history
  • Loading branch information
shnhrrsn committed Dec 2, 2017
1 parent a95ec47 commit ebe5e58
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 72 deletions.
77 changes: 5 additions & 72 deletions src/Stone/Parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import './Parsers'
import './Contexts/DirectiveArgs'
import './Contexts/PreserveSpace'

import './Support/MakeNode'

import './Tokens/StoneOutput'
import './Tokens/StoneDirective'

Expand All @@ -20,6 +22,7 @@ export class Parser {
template.type = 'StoneTemplate'
template.pathname = this._stoneTemplatePathname
this._stoneTemplate = template
this.make = new MakeNode(this)

const node = this.startNode()
this.nextToken()
Expand All @@ -28,7 +31,7 @@ export class Parser {

template.output = new acorn.Node(this)
template.output.type = 'StoneOutputBlock'
template.output.body = this._createBlockStatement(result.body)
template.output.body = this.make.block(result.body)

result.body = [ template ]

Expand All @@ -50,10 +53,6 @@ export class Parser {
return next.call(this, type)
}

skipSpace(next, ...args) {
return next.call(this, ...args)
}

readToken(next, code) {
if(code === 64 && !this._isCharCode(123, 1)) {
this.pos++
Expand Down Expand Up @@ -92,7 +91,7 @@ export class Parser {
// we can leverage the built in acorn functionality
// for parsing things like for loops without it
// trying to parse the block
return this._createBlockStatement([ ])
return this.make.block([ ])
}

switch(this.type) {
Expand Down Expand Up @@ -261,72 +260,6 @@ export class Parser {
return [ args ]
}

_createIdentifier(identifier) {
const node = new acorn.Node(this)
node.type = 'Identifier'
node.name = identifier
return node
}

_maybeCreateIdentifier(name) {
if(typeof name !== 'string') {
return name
}

return this._createIdentifier(name)
}

_createBlockStatement(statements) {
const node = new acorn.Node(this)
node.type = 'BlockStatement'
node.body = statements
return node
}

_createEmptyNode() {
const node = new acorn.Node(this)
node.type = 'BlankExpression'
return node
}

_createAssignment(left, right, operator = '=') {
const node = this.startNodeAt(this.start, this.startLoc)
node.operator = operator
node.left = this._maybeCreateIdentifier(left)
node.right = right

return this.finishNode(node, 'AssignmentExpression')
}

_createDeclaration(lhs, rhs, kind = 'const') {
const declarator = this.startNode()
declarator.id = this._maybeCreateIdentifier(lhs)
declarator.init = rhs
this.finishNode(declarator, 'VariableDeclarator')

const declaration = this.startNode()
declaration.declarations = [ declarator ]
declaration.kind = kind
return this.finishNode(declaration, 'VariableDeclaration')
}

_createLiteral(value) {
const node = this.startNode()
node.value = value
node.raw = value
return this.finishNode(node, 'Literal')
}

_createReturn(value) {
const declarator = this.startNode()

if(value) {
declarator.argument = this._maybeCreateIdentifier(value)
}

return this.finishNode(declarator, 'ReturnStatement')
}

_debug(message = 'DEBUG', peek = false) {
let debug = {
start: this.start,
Expand Down
114 changes: 114 additions & 0 deletions src/Stone/Support/MakeNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import './MockParser'

export class MakeNode {

constructor(parser = null) {
this.parser = parser || new MockParser
}

identifier(identifier) {
const node = this.parser.startNode()
node.name = identifier
return this.parser.finishNode(node, 'Identifier')
}

auto(type) {
if(typeof type !== 'string') {
return type
}

return this.identifier(type, this.parser)
}

new(callee, args) {
const node = this.parser.startNode()
node.type = 'NewExpression'
node.callee = this.auto(callee)
node.arguments = Array.isArray(args) ? args.map(arg => this.auto(arg)) : [ this.auto(args) ]
return this.parser.finishNode(node, 'NewExpression')
}

object(properties) {
const node = this.parser.startNode()
node.type = 'ObjectExpression'
node.properties = properties || [ ]
return this.parser.finishNode(node, 'ObjectExpression')
}

property(key, value) {
const node = this.parser.startNode()
node.key = this.auto(key)

if(!value.isNil) {
node.value = this.auto(value)
node.kind = 'init'
}

return this.parser.finishNode(node, 'Property')
}

spread(type) {
const node = this.parser.startNode()
node.argument = this.auto(type, this.parser)
return this.parser.finishNode(node, 'SpreadElement')
}

assignment(left, right, operator = '=') {
const node = this.parser.startNode()
node.operator = operator
node.left = this.auto(left)
node.right = this.auto(right)
return this.parser.finishNode(node, 'AssignmentExpression')
}

declaration(left, right, kind = 'const') {
const declarator = this.parser.startNode()
declarator.id = this.auto(left)
declarator.init = this.auto(right)
this.parser.finishNode(declarator, 'VariableDeclarator')

const declaration = this.parser.startNode()
declaration.declarations = [ declarator ]
declaration.kind = kind
return this.parser.finishNode(declaration, 'VariableDeclaration')
}

literal(value) {
const node = this.parser.startNode()
node.value = value
node.raw = value
return this.parser.finishNode(node, 'Literal')
}

return(value) {
const node = this.parser.startNode()

if(!value.isNil) {
node.argument = this.auto(value)
}

return this.parser.finishNode(node, 'ReturnStatement')
}

block(statements) {
const node = this.parser.startNode()
node.body = statements
return this.parser.finishNode(node, 'BlockStatement')
}


null() {
const node = this.parser.startNode()
node.type = 'Literal'
node.value = null
node.raw = 'null'
return this.parser.finishNode(node, 'Literal')
}

empty() {
return this.parser.finishNode(this.parser.startNode(), 'StoneEmptyExpression')
}

}

export const make = new MakeNode
29 changes: 29 additions & 0 deletions src/Stone/Support/MockParser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const { Node } = require('acorn')

export class MockParser {

options = { }

startNode() {
return new Node(this)
}

startNodeAt(pos, loc) {
return new Node(this, pos, loc)
}

finishNode(node, type) {
return this.finishNodeAt(node, type)
}

finishNodeAt(node, type, pos) {
node.type = type

if(!pos.isNil) {
node.end = pos
}

return node
}

}

0 comments on commit ebe5e58

Please sign in to comment.