Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arrow function #319

Merged
merged 5 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions ast/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,23 @@ type (
DeclarationList []*VariableDeclaration
}

ConciseBody interface {
Node
_conciseBody()
}

ExpressionBody struct {
Expression Expression
}

ArrowFunctionLiteral struct {
Start file.Idx
ParameterList *ParameterList
Body ConciseBody
Source string
DeclarationList []*VariableDeclaration
}

Identifier struct {
Name unistring.String
Idx file.Idx
Expand Down Expand Up @@ -238,6 +255,7 @@ func (*CallExpression) _expressionNode() {}
func (*ConditionalExpression) _expressionNode() {}
func (*DotExpression) _expressionNode() {}
func (*FunctionLiteral) _expressionNode() {}
func (*ArrowFunctionLiteral) _expressionNode() {}
func (*Identifier) _expressionNode() {}
func (*NewExpression) _expressionNode() {}
func (*NullLiteral) _expressionNode() {}
Expand Down Expand Up @@ -497,6 +515,9 @@ func (*SpreadElement) _property() {}

func (*Identifier) _bindingTarget() {}

func (*BlockStatement) _conciseBody() {}
func (*ExpressionBody) _conciseBody() {}

// ==== //
// Node //
// ==== //
Expand Down Expand Up @@ -525,6 +546,7 @@ func (self *CallExpression) Idx0() file.Idx { return self.Callee.Idx0() }
func (self *ConditionalExpression) Idx0() file.Idx { return self.Test.Idx0() }
func (self *DotExpression) Idx0() file.Idx { return self.Left.Idx0() }
func (self *FunctionLiteral) Idx0() file.Idx { return self.Function }
func (self *ArrowFunctionLiteral) Idx0() file.Idx { return self.Start }
func (self *Identifier) Idx0() file.Idx { return self.Idx }
func (self *NewExpression) Idx0() file.Idx { return self.New }
func (self *NullLiteral) Idx0() file.Idx { return self.Idx }
Expand Down Expand Up @@ -566,6 +588,7 @@ func (self *Binding) Idx0() file.Idx { return self.Target.Idx0() }
func (self *ForLoopInitializerVarDeclList) Idx0() file.Idx { return self.List[0].Idx0() }
func (self *PropertyShort) Idx0() file.Idx { return self.Name.Idx }
func (self *PropertyKeyed) Idx0() file.Idx { return self.Key.Idx0() }
func (self *ExpressionBody) Idx0() file.Idx { return self.Expression.Idx0() }

// ==== //
// Idx1 //
Expand All @@ -582,6 +605,7 @@ func (self *CallExpression) Idx1() file.Idx { return self.RightParenthesi
func (self *ConditionalExpression) Idx1() file.Idx { return self.Test.Idx1() }
func (self *DotExpression) Idx1() file.Idx { return self.Identifier.Idx1() }
func (self *FunctionLiteral) Idx1() file.Idx { return self.Body.Idx1() }
func (self *ArrowFunctionLiteral) Idx1() file.Idx { return self.Body.Idx1() }
func (self *Identifier) Idx1() file.Idx { return file.Idx(int(self.Idx) + len(self.Name)) }
func (self *NewExpression) Idx1() file.Idx { return self.RightParenthesis + 1 }
func (self *NullLiteral) Idx1() file.Idx { return file.Idx(int(self.Idx) + 4) } // "null"
Expand Down Expand Up @@ -656,3 +680,5 @@ func (self *PropertyShort) Idx1() file.Idx {
}

func (self *PropertyKeyed) Idx1() file.Idx { return self.Value.Idx1() }

func (self *ExpressionBody) Idx1() file.Idx { return self.Expression.Idx1() }
4 changes: 4 additions & 0 deletions builtin_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ repeat:
switch f := obj.self.(type) {
case *funcObject:
return newStringValue(f.src)
case *arrowFuncObject:
return newStringValue(f.src)
case *nativeFuncObject:
return newStringValue(fmt.Sprintf("function %s() { [native code] }", nilSafe(f.getStr("name", nil)).toString()))
case *boundFuncObject:
Expand All @@ -46,6 +48,8 @@ repeat:
switch c := f.target.self.(type) {
case *funcObject:
name = c.src
case *arrowFuncObject:
name = c.src
case *nativeFuncObject:
name = nilSafe(f.getStr("name", nil)).toString().String()
case *boundFuncObject:
Expand Down
6 changes: 5 additions & 1 deletion compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ type scope struct {

// is a function or a top-level lexical environment
function bool
// is an arrow function's top-level lexical environment (functions only)
arrow bool
// is a variable environment, i.e. the target for dynamically created var bindings
variable bool
// a function scope that has at least one direct eval() and non-strict, so the variables can be added dynamically
Expand Down Expand Up @@ -365,6 +367,8 @@ func (p *Program) _dumpCode(indent string, logger func(format string, args ...in
logger("%s %d: %T(%v)", indent, pc, ins, ins)
if f, ok := ins.(*newFunc); ok {
f.prg._dumpCode(indent+">", logger)
} else if f, ok := ins.(*newArrowFunc); ok {
f.prg._dumpCode(indent+">", logger)
}
}
}
Expand Down Expand Up @@ -395,7 +399,7 @@ func (s *scope) lookupName(name unistring.String) (binding *binding, noDynamics
return
}
}
if name == "arguments" && curScope.function {
if name == "arguments" && curScope.function && !curScope.arrow {
curScope.argsNeeded = true
binding, _ = curScope.bindName(name)
return
Expand Down
Loading