Skip to content

Commit

Permalink
Semantically check function calls
Browse files Browse the repository at this point in the history
Previously most checking of function calls was done in kernel,
but move this to the semantic pass. Also change the parser so it
doesn't convert a primitive function call to cast and instead lets
the semantic pass do this.

Closes #4593
  • Loading branch information
mattnibs committed Oct 18, 2023
1 parent 24b9cc9 commit 94924cf
Show file tree
Hide file tree
Showing 8 changed files with 1,599 additions and 1,661 deletions.
63 changes: 15 additions & 48 deletions compiler/kernel/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,55 +282,9 @@ func (b *Builder) compileAssignment(node *dag.Assignment) (expr.Assignment, erro
return expr.Assignment{LHS: lhs, RHS: rhs}, err
}

func shaperOps(name string) expr.ShaperTransform {
switch name {
case "cast":
return expr.Cast
case "crop":
return expr.Crop
case "fill":
return expr.Fill
case "fit":
return expr.Crop | expr.Fill
case "order":
return expr.Order
case "shape":
return expr.Cast | expr.Fill | expr.Order
default:
return 0
}

}

func isShaperFunc(name string) bool {
return shaperOps(name) != 0
}

func (b *Builder) compileShaper(node dag.Call) (expr.Evaluator, error) {
args := node.Args
if len(args) == 1 {
args = append([]dag.Expr{&dag.This{Kind: "This"}}, args...)
}
if len(args) < 2 {
return nil, function.ErrTooFewArgs
}
if len(args) > 2 {
return nil, function.ErrTooManyArgs
}
field, err := b.compileExpr(args[0])
if err != nil {
return nil, err
}
typExpr, err := b.compileExpr(args[1])
if err != nil {
return nil, err
}
return expr.NewShaper(b.zctx(), field, typExpr, shaperOps(node.Name))
}

func (b *Builder) compileCall(call dag.Call) (expr.Evaluator, error) {
if isShaperFunc(call.Name) {
return b.compileShaper(call)
if tf := expr.NewShaperTransform(call.Name); tf != 0 {
return b.compileShaper(call, tf)
}
var path field.Path
// First check if call is to a user defined function, otherwise check for
Expand All @@ -355,6 +309,19 @@ func (b *Builder) compileCall(call dag.Call) (expr.Evaluator, error) {
return expr.NewCall(b.zctx(), fn, exprs), nil
}

func (b *Builder) compileShaper(node dag.Call, tf expr.ShaperTransform) (expr.Evaluator, error) {
args := node.Args
field, err := b.compileExpr(args[0])
if err != nil {
return nil, err
}
typExpr, err := b.compileExpr(args[1])
if err != nil {
return nil, err
}
return expr.NewShaper(b.zctx(), field, typExpr, tf)
}

func (b *Builder) compileExprs(in []dag.Expr) ([]expr.Evaluator, error) {
var exprs []expr.Evaluator
for _, e := range in {
Expand Down
19 changes: 1 addition & 18 deletions compiler/parser/parser.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -8365,7 +8365,7 @@ function peg$parse(input, options) {
var s0, s1, s2, s3, s4, s5, s6, s7;

s0 = peg$currPos;
s1 = peg$parseCastType();
s1 = peg$parseTypeLiteral();
if (s1 !== peg$FAILED) {
s2 = peg$parse__();
if (s2 !== peg$FAILED) {
Expand Down Expand Up @@ -11613,23 +11613,6 @@ function peg$parse(input, options) {
return s0;
}

function peg$parseCastType() {
var s0, s1;

s0 = peg$parseTypeLiteral();
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = peg$parsePrimitiveType();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c410(s1);
}
s0 = s1;
}

return s0;
}

function peg$parseType() {
var s0;

Expand Down
Loading

0 comments on commit 94924cf

Please sign in to comment.