Skip to content

padraicbc/gojsp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Very early attempt at creating an ANTLR visitor for javascript files using GO. Going to change like Irish weather so don't expect things to stay the same any time soon.

The base is the result of running what is described here

The vast folder is the implementation so far toward creating an ast which will allow easy manipulation/translation of the original source. Thre are a few example functions in the exampls folder including how to parse and manipulate a single expression.

import (
    "log"
    antlr "github.com/padraicbc/antlr4"
    "github.com/padraicbc/gojsp/base"
    "github.com/padraicbc/gojsp/vast"
)



code := `i + j;`
v := vast.NewVisitor(code)
// do whatever with errors
go v.DefaultError()
// start at ExpressionSequence
tree := v.Parser.ExpressionSequence()
exp := visit(tree, v).(*vast.ExpressionSequence)

expc := exp.FirstChild().(*vast.LRExpression)

fmt.Println(expc.Left().(vast.Token).Value(), expc.OP().Value(), expc.Right().(vast.Token).Value())
// change OP
expc.OP().SetValue("/")
expc.Right().(vast.Token).SetValue("1000")
fmt.Println(expc.Left().(vast.Token).Value(), expc.OP().Value(), expc.Right().(vast.Token).Value())

// reuse lexer and parser
v.Stream.Seek(0)
v.Lexer.SetInputStream(v.Stream)
tokenStream := antlr.NewCommonTokenStream(v.Lexer, antlr.TokenDefaultChannel)
v.Parser.SetInputStream(tokenStream)

tree2 := v.Parser.ExpressionStatement()
exp2 := visit(tree2, v).(*vast.ExpressionStatement).FirstChild()

expc = exp2.FirstChild().(*vast.LRExpression)
// can be any singleExpression so any VNode
fmt.Println(expc.Left().(vast.Token).Value(), expc.OP().Value(), expc.Right().(vast.Token).Value())

expc = exp2.FirstChild().(*vast.LRExpression)
// can be any singleExpression so any VNode
fmt.Println(expc.Left().(vast.Token).Value(), expc.OP().Value(), expc.Right().(vast.Token).Value())

And a very incomplete conversion from arrow to es5 functions but it shows the general idea:

code := `
// Arrow Function Break Down
// 1. Remove the word "function" and place arrow between the argument and opening body bracket
(a) => {
return a + 100;
}

// 2. Remove the body brackets and word "return" -- the return is implied.
(b) => b + 100;

// 3. Remove the argument parentheses
c => c 

// Arrow Function
(a, b) => {
let chuck = 42;
return a + b + chuck;
}
`

v := vast.NewVisitor(code)
tree := v.Parser.Program()
go v.DefaultError()
// v.Debug = true

rfs := visit(tree, v).(*vast.Program).Body
// Statement ->ExpressionStatememts -> ExpressionSequence
for _, fn := range rfs {

	var trans string
	// all with one child
	af := fn.FirstChild().FirstChild().FirstChild().(*vast.ArrowFunction)

	// either has a function body with {} of a single expression.
	if af.Body.SingleExpression != nil {
		// can be there or not
		var open, close string
		if af.FunctionParameters.OpenParen == nil {
			open, close = "(", ")"
		}

		trans = fmt.Sprintf("function%s%s%s {\n\treturn %s;\n}",
			open, af.FunctionParameters.Source, close, af.Body.SingleExpression.Code())

	} else {

		trans = fmt.Sprintf("function%s %s", af.FunctionParameters.Source, af.Body.Source)

	}
	fmt.Println("After ->", trans)

}

Quite verbose but more about getting it working than pretty to start...

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published