Skip to content

Commit

Permalink
feature: add cfunction declaration for cffi
Browse files Browse the repository at this point in the history
  • Loading branch information
douyixuan committed Jul 10, 2024
1 parent f87367d commit 84822b2
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
1 change: 1 addition & 0 deletions compiler/lexer/keywords.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var keywords = map[string]struct{}{
"if": {},
"else": {},
"function": {},
"cfunction": {},
"return": {},
"type": {},
"table": {},
Expand Down
1 change: 1 addition & 0 deletions compiler/parser/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ type DefineFuncNode struct {
IsNamed bool

IsMethod bool
IsCFunc bool

MethodOnType *SingleTypeNode
IsPointerReceiver bool
Expand Down
10 changes: 9 additions & 1 deletion compiler/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif
return outerConditionNode
}

// "cfunction" is function without function body
// "function" gets converted into a DefineFuncNode
// the keyword "function" is followed by
// - a IDENTIFIER (function name)
Expand All @@ -339,8 +340,11 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif
// method: func (a abc) abc() {
// value func: func (a abc) {

if current.Val == "function" {
if current.Val == "function" || current.Val == "cfunction" {
defineFunc := &DefineFuncNode{}
if current.Val == "cfunction" {
defineFunc.IsCFunc = true
}
p.i++

var argsOrMethodType []*NameNode
Expand Down Expand Up @@ -463,6 +467,10 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif

defineFunc.ReturnValues = retTypesNodeNames

if current.Val == "cfunction" {
return p.aheadParse(defineFunc)
}

openBracket := p.lookAhead(0)
if openBracket.Type != lexer.OPERATOR || openBracket.Val != "{" {
panic("func arguments must be followed by {. Got " + openBracket.Val)
Expand Down
43 changes: 43 additions & 0 deletions compiler/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,46 @@ func TestPramga(t *testing.T) {

assert.Equal(t, expected, Parse(input, &option.Options{Debug: false}))
}

func TestFunction(t *testing.T) {
input := []lexer.Item{
{Type: lexer.KEYWORD, Val: "cfunction", Line: 1},
{Type: lexer.IDENTIFIER, Val: "foo", Line: 1},
{Type: lexer.OPERATOR, Val: "(", Line: 1},
{Type: lexer.OPERATOR, Val: ")", Line: 1},
{Type: lexer.IDENTIFIER, Val: "int32", Line: 1},
{Type: lexer.EOL},
{Type: lexer.EOF},
}

/*
pramga cellscript 0.0.1
*/

expected := &FileNode{
Instructions: []Node{
&DefineFuncNode{
Name: "foo",
IsNamed: true,
IsMethod: false,
IsCFunc: true,

MethodOnType: nil,
IsPointerReceiver: false,
InstanceName: "",

Arguments: nil,
ReturnValues: []*NameNode{
&NameNode{
Type: &SingleTypeNode{
TypeName: "int32",
},
},
},
Body: nil,
},
},
}

assert.Equal(t, expected, Parse(input, &option.Options{Debug: false}))
}

0 comments on commit 84822b2

Please sign in to comment.