Skip to content

Commit

Permalink
asm/parser: Implement parsing of function headers.
Browse files Browse the repository at this point in the history
  • Loading branch information
mewmew committed Jun 21, 2015
1 parent d1d7a46 commit ec21daf
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
46 changes: 40 additions & 6 deletions asm/parser/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/llir/llvm/asm/token"
"github.com/llir/llvm/ir"
"github.com/llir/llvm/ir/types"
"github.com/mewkiz/pkg/errutil"
)

Expand Down Expand Up @@ -48,29 +49,62 @@ func (p *parser) parseFuncDef() error {
// parseFuncHeader parses a function header consisting of a return argument, a
// function name and zero or more function arguments.
//
// FuncHeader = FuncResult FuncName "(" FuncParams ")" .
// FuncHeader = FuncResult FuncName "(" FuncArgs ")" .
//
// FuncName = Global .
// FuncArgs = [ FuncArg { "," FuncArg } [ "," "..." ] ] | "..." .
// FuncArg = [ Local ] Type .
func (p *parser) parseFuncHeader() (header *ir.Function, err error) {
// Parse return type.
result, err := p.parseType()
if err != nil {
return nil, err
}

// Parse function name.
name, ok := p.tryGlobal()
if !ok {
return nil, errutil.New("expected function name")
}
header = &ir.Function{
Name: name,
}

// Parse function argument list.
if !p.accept(token.Lparen) {
return nil, errors.New("expected '(' in function argument list")
}
// TODO: Don't use parseFuncType as it is specifically for function types
// which do not include parameter names. Write a custom implementation for
// function declarations and function definitions.
_ = result
//header.Sig, err = p.parseFunc(result)
var params []types.Type
variadic := false
for i := 0; ; i++ {
if i > 0 && !p.accept(token.Comma) {
break
}
if param, ok := p.tryType(); ok {
params = append(params, param)
// Argument name.
if arg, ok := p.tryLocal(); ok {
header.Args = append(header.Args, arg)
} else {
// Unnamed function argument.
header.Args = append(header.Args, "")
}
} else if p.accept(token.Ellipsis) {
variadic = true
break
} else {
return nil, errutil.New("expected type")
}
}
if !p.accept(token.Rparen) {
return nil, errutil.New("expected ')' at end of argument list")
}

// Create function signature.
header.Sig, err = types.NewFunc(result, params, variadic)
if err != nil {
return nil, errutil.Err(err)
}
return header, err
}

Expand Down
4 changes: 2 additions & 2 deletions asm/parser/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,8 @@ func (p *parser) parseStructType(packed bool) (*types.Struct, error) {
return types.NewStruct(fields, packed)
}

// parseFuncType parses a function type. A result type, an optional function
// name and a "(" token has already been consumed.
// parseFuncType parses a function type. A result type and a "(" token has
// already been consumed.
//
// Syntax:
// FuncType = FuncResult "(" FuncParams ")" .
Expand Down
2 changes: 2 additions & 0 deletions ir/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type Function struct {
Name string
// Function signature.
Sig *types.Func
// Function argument names; len(Args) == len(Sig.Params).
Args []string
// Basic blocks of the function, or nil if function declaration.
Blocks []*BasicBlock
}

0 comments on commit ec21daf

Please sign in to comment.