Skip to content

Commit

Permalink
Merge branch 'master' of github.com:c9s/gutscript
Browse files Browse the repository at this point in the history
  • Loading branch information
c9s committed Oct 20, 2013
2 parents 7ae7da7 + 5df2224 commit ec38931
Show file tree
Hide file tree
Showing 19 changed files with 1,148 additions and 868 deletions.
6 changes: 3 additions & 3 deletions src/gutscript/ast/assignment.go
Expand Up @@ -3,14 +3,14 @@ package ast
/*
*/
type AssignStatement struct {
type Assignment struct {
Variable Node
Expr Node
Statement
}

func CreateAssignStatement(variable Node, expr Node) Node {
return AssignStatement{
func CreateAssignment(variable Node, expr Node) Node {
return Assignment{
Variable: variable,
Expr: expr,
}
Expand Down
23 changes: 14 additions & 9 deletions src/gutscript/ast/class.go
@@ -1,21 +1,26 @@
package ast

type ClassStatement struct {
Name string
Properties []Node
Methods []Node
type Class struct {
Name string
// Properties []Node
// Methods []Node
Super *string
Interfaces []string
Body *StatementList
}

func CreateClassStatement(className string) Node {
return ClassStatement{className, nil, nil, nil, []string{}}
func CreateClass(className string) Node {
return Class{className, nil, []string{}, nil}
}

func (self ClassStatement) SetSuperClass(className string) {
func (self *Class) SetSuper(className string) {
self.Super = &className
}

func (self ClassStatement) AddInterface(intf string) {
self.Interfaces = append(self.Interfaces, intf)
func (self *Class) AddInterface(inf string) {
self.Interfaces = append(self.Interfaces, inf)
}

func (self *Class) SetInterfaces(infs []string) {
self.Interfaces = infs
}
14 changes: 14 additions & 0 deletions src/gutscript/ast/class_member.go
@@ -0,0 +1,14 @@
package ast

type ClassMember struct {
Name string
Value Node
}

func CreateClassMember(name string) ClassMember {
return ClassMember{name, nil}
}

func (self *ClassMember) SetValue(val Node) {
self.Value = val
}
6 changes: 5 additions & 1 deletion src/gutscript/ast/expr.go
Expand Up @@ -12,7 +12,11 @@ type Expr struct {
Parenthesis bool
}

func CreateExpr(op int, left, right Node) Node {
func CreateUnaryExpr(op int, val Node) UnaryExpr {
return UnaryExpr{op, val}
}

func CreateExpr(op int, left, right Node) Expr {
return Expr{
Op: op,
Left: left,
Expand Down
2 changes: 1 addition & 1 deletion src/gutscript/ast/function.go
Expand Up @@ -12,6 +12,6 @@ type FunctionParam struct {
Default Node
}

func CreateFunction(name string, params []FunctionParam, stmts *StatementList) Node {
func CreateFunction(name string, params []FunctionParam, stmts *StatementList) Function {
return Function{name, params, stmts}
}
2 changes: 1 addition & 1 deletion src/gutscript/ast/function_call.go
Expand Up @@ -5,6 +5,6 @@ type FunctionCall struct {
Params []Node
}

func CreateFunctionCall(name string, params []Node) Node {
func CreateFunctionCall(name string, params []Node) FunctionCall {
return FunctionCall{name, params}
}
57 changes: 44 additions & 13 deletions src/gutscript/codegen/php/visitor.go
Expand Up @@ -16,14 +16,18 @@ func (self *Visitor) IndentSpace() string {
return strings.Repeat(" ", self.indent)
}

func (self *Visitor) Visit(n ast.Node) string {
func (self *Visitor) Visit(n ast.Node) (out string) {
// fmt.Printf("visit %#v\n", n)
if stmts, ok := n.(*ast.StatementList); ok {
var output string
for _, stmt := range *stmts {
output += self.IndentSpace() + self.Visit(stmt)
var stmtlen = len(*stmts)
for i, stmt := range *stmts {
if _, ok := stmt.(ast.ExprStatement); ok && i+1 == stmtlen {
out += self.IndentSpace() + "return " + self.Visit(stmt)
} else {
out += self.IndentSpace() + self.Visit(stmt)
}
}
return output
return out
}
if variable, ok := n.(ast.Variable); ok {
return "$" + variable.Identifier
Expand All @@ -48,11 +52,41 @@ func (self *Visitor) Visit(n ast.Node) string {
}
return fmt.Sprintf("%s %c %s", self.Visit(expr.Left), expr.Op, self.Visit(expr.Right))
}
if stmt, ok := n.(ast.AssignStatement); ok {
return self.Visit(stmt.Variable) + " = " + self.Visit(stmt.Expr) + ";\n"

if stmt, ok := n.(ast.Assignment); ok {
return self.IndentSpace() + self.Visit(stmt.Variable) + " = " + self.Visit(stmt.Expr) + ";\n"
}

if cls, ok := n.(ast.Class); ok {
out = "class " + cls.Name

if cls.Super != nil {
out += " extends " + *cls.Super
}

if len(cls.Interfaces) > 0 {
out += " implements "
out += strings.Join(cls.Interfaces, ", ")
}

out += " {\n"
if cls.Body != nil {
self.indent++
out += self.Visit(cls.Body)
self.indent--
}
out += "}\n"
return out
}
if member, ok := n.(ast.ClassMember); ok {
out += self.IndentSpace() + "public $" + member.Name
if member.Value != nil {
out += " = " + self.Visit(member.Value)
}
out += ";\n"
return out
}
if stmt, ok := n.(*ast.IfStatement); ok {
var out string = ""
out += self.IndentSpace() + "if ( " + self.Visit(stmt.Expr) + " ) {\n"
self.indent++
out += self.Visit(stmt.Body)
Expand All @@ -75,7 +109,6 @@ func (self *Visitor) Visit(n ast.Node) string {
return out
}
if stmt, ok := n.(ast.ElseIfStatement); ok {
var out string = ""
out += self.IndentSpace() + " elseif ( " + self.Visit(stmt.Expr) + " ) {\n"
self.indent++
out += self.Visit(stmt.Body)
Expand All @@ -84,13 +117,12 @@ func (self *Visitor) Visit(n ast.Node) string {
return out
}
if stmt, ok := n.(ast.ReturnStatement); ok {
return "return " + self.Visit(stmt.Expr) + ";\n"
return self.IndentSpace() + "return " + self.Visit(stmt.Expr) + ";\n"
}
if stmt, ok := n.(ast.ExprStatement); ok {
return self.Visit(stmt.Expr) + ";\n"
return self.IndentSpace() + self.Visit(stmt.Expr) + ";\n"
}
if fnc, ok := n.(ast.FunctionCall); ok {
var out string
out = fnc.Name + "("
fields := []string{}
for _, param := range fnc.Params {
Expand All @@ -101,7 +133,6 @@ func (self *Visitor) Visit(n ast.Node) string {
return out
}
if fn, ok := n.(ast.Function); ok {
var out string = ""
out += self.IndentSpace() + "function " + fn.Name + "("
if len(fn.Params) > 0 {
fields := []string{}
Expand Down
11 changes: 6 additions & 5 deletions src/gutscript/lexer.go
Expand Up @@ -10,11 +10,12 @@ type stateFn func(*GutsLex) stateFn

type GutsLex struct {
// the line
Input string
Line int
Start int
Pos int
state stateFn
Input string
Line int
Start int
Pos int
IndentLevel int
state stateFn

// rollback position
rollbackPos int
Expand Down
37 changes: 17 additions & 20 deletions src/gutscript/lexer_states.go
Expand Up @@ -17,6 +17,8 @@ var LexKeywords = map[string]int{
"return": T_RETURN,
"extends": T_EXTENDS,
"does": T_DOES,
"new": T_NEW,
"clone": T_CLONE,
}

func (l *GutsLex) emitIfKeywordMatches() bool {
Expand Down Expand Up @@ -89,19 +91,9 @@ func lexStart(l *GutsLex) stateFn {
}
l.backup()

// emit a newline (can be the end of block)
// l.emit(T_NEWLINE)

// c = l.peek()
if c == eof {
// if we're in an indent block, and it's the end of file.
// we should treat the newline as a block end.
if l.space > 0 {
l.emit(T_OUTDENT)
} else {
l.ignore()
}
return nil
return lexStart
}

// reset space info
Expand All @@ -119,32 +111,35 @@ func lexStart(l *GutsLex) stateFn {
l.emit(T_NEWLINE)
} else if l.space < l.lastSpace {
l.emit(T_OUTDENT)
l.emit(T_NEWLINE)
l.emit(T_NEWLINE) // means end of statement
l.IndentLevel--
} else if l.space > l.lastSpace {
l.IndentLevel++
l.emit(T_INDENT)
}
return lexStart
} else if l.emitIfMatch("&&", T_BOOLEAN_AND) || l.emitIfMatch("||", T_BOOLEAN_OR) {
return lexStart
} else if l.emitIfMatch("==", T_EQUAL) || l.emitIfMatch(">=", T_GT_EQUAL) || l.emitIfMatch("<=", T_LT_EQUAL) {
return lexStart
} else if c == '=' && l.peekMore(2) != '=' {
l.next()
l.emit(TokenType(c))
} else if l.emitIfKeywordMatches() {
return lexStart
} else if l.accept("+-*|&[]{}()<>,") {
} else if l.accept("+-*|&[]{}()<>,=@") {
l.emit(TokenType(c))
return lexStart
} else if l.lastTokenType == T_NUMBER && l.emitIfMatch("..", T_RANGE_OPERATOR) {
return lexStart
} else if c == '"' || c == '\'' {
return lexString
} else if l.emitIfKeywordMatches() {
return lexStart
} else if unicode.IsLetter(c) {
return lexIdentifier
} else if c == eof {
// l.emit(T_EOF)
if l.IndentLevel > 0 {
for i := 0; i < l.IndentLevel; i++ {
l.emit(T_OUTDENT)
l.emit(T_NEWLINE)
}
}
return nil
} else {
panic(fmt.Errorf("unknown token %c\n", c))
Expand Down Expand Up @@ -230,7 +225,7 @@ func lexIgnoreSpaces(l *GutsLex) stateFn {
c = l.next()
if c == eof {
l.ignore()
return nil
return lexStart
}
if c != ' ' {
break
Expand All @@ -257,8 +252,10 @@ func lexIndentSpaces(l *GutsLex) stateFn {
} else if l.space < l.lastSpace {
l.emit(T_OUTDENT)
l.emit(T_NEWLINE)
l.IndentLevel--
} else if l.space > l.lastSpace {
l.emit(T_INDENT)
l.IndentLevel++
}
return lexStart
}
Expand Down

0 comments on commit ec38931

Please sign in to comment.