Skip to content

Commit

Permalink
internal/core/runtime: new attribute name for extern
Browse files Browse the repository at this point in the history
Right now, we only allow one type of extern attribute in
a file. At the file level, we define @extern(kind). Fields
within the file can then be associated with an @extern
attribute that is interpreted as defined by kind.

This approach may work for lower-level functionality like
support for WASM, but it seems a bit unintuitive for embed.
Instead, we suggest that after a file-level @extern(kind)
declaration the field attributes take the form @kind(). This
is what is implemented here.

This has the additional benefit that we could more easily
allow different types of extern fields within a single file.

Note that the original reason to reuse @extern for field
attributes was to avoid a proliferation of attributes.
This namespace encrouching is still a bit mitigated by the
@extern(kind) attribute. In the future we can find a different
mechanism to define attributes scoped by domain.

Issue #2031

Signed-off-by: Marcel van Lohuizen <[email protected]>
Change-Id: I28b1fdd0f0a85c46a544f71bbff40a7772e60873
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1196717
Reviewed-by: Daniel Martí <[email protected]>
Unity-Result: CUE porcuepine <[email protected]>
TryBot-Result: CUEcueckoo <[email protected]>
  • Loading branch information
mpvl committed Jun 25, 2024
1 parent a1c1cd7 commit b70e543
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 28 deletions.
7 changes: 4 additions & 3 deletions internal/core/runtime/extern.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,22 +245,23 @@ func (d *externDecorator) markExternFieldAttr(kind string, decls []ast.Decl) (er

case *ast.Attribute:
key, body := x.Split()
if key != "extern" {
// Support old-style and new-style extern attributes.
if key != "extern" && key != kind {
break
}

lastField := len(fieldStack) - 1
if lastField < 0 {
errs = errors.Append(errs, errors.Newf(x.Pos(),
"extern attribute not associated with field"))
"@%s attribute not associated with field", kind))
return true
}

f := fieldStack[lastField]

if _, ok := d.fields[f]; ok {
errs = errors.Append(errs, errors.Newf(x.Pos(),
"duplicate extern attributes"))
"duplicate @%s attributes", kind))
return true
}

Expand Down
6 changes: 3 additions & 3 deletions internal/core/runtime/testdata/basic.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
package foo


Foo: _ @extern(file1.xx, abi=c, sig="func(int)int")
Foo: _ @test(file1.xx, abi=c, sig="func(int)int")

Rename: _ @extern(file1.xx, name=Emaner, abi=c, sig="func(int)int")
Rename: _ @test(file1.xx, name=Emaner, abi=c, sig="func(int)int")

-- file2.cue --
@extern("test")
Expand All @@ -17,7 +17,7 @@ package foo

Bar: {
@other()
@extern(file2.xx, abi=c, sig="func(int)int")
@test(file2.xx, abi=c, sig="func(int)int")
_
}

Expand Down
2 changes: 1 addition & 1 deletion internal/core/runtime/testdata/compile.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

package ok

foo: _ @extern("file.xx", fail)
foo: _ @test("file.xx", fail)
-- out/extern --
can't load from external module: TEST: fail compilation:
./compile.cue:5:8
32 changes: 16 additions & 16 deletions internal/core/runtime/testdata/errors.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,30 @@ package foo

package foo

Fn1: _ @extern("file1.xx" abi sig)
Fn1: _ @test("file1.xx" abi sig)

-- empty_extern.cue --
@extern()

package foo

Fn2: _ @extern("file1.xx" abi sig)
Fn2: _ @test("file1.xx" abi sig)


-- unknown_interpreter.cue --
@extern("wazem")

package foo

Fn3: _ @extern("file1.xx" abi sig)
Fn3: _ @wazem("file1.xx" abi sig)

-- double_extern_a.cue --
@extern("test")
@extern("test")

package foo

Fn4a: _ @extern("file1.xx")
Fn4a: _ @test("file1.xx")

-- double_extern_b.cue --
@extern("test")
Expand All @@ -45,14 +45,14 @@ Fn4a: _ @extern("file1.xx")

package foo

Fn4b: _ @extern("file1.xx")
Fn4b: _ @test("file1.xx")

-- package_attr.cue --
@extern("test")

package foo

@extern("file1.xx")
@test("file1.xx")
Fn5: _

-- duplicate.cue --
Expand All @@ -61,39 +61,39 @@ Fn5: _
package foo


Fn6: _ @extern("file1.xx",sig=func(int)int) @extern("file1.xx", sig=func(int)bool)
Fn6: _ @test("file1.xx",sig=func(int)int) @test("file1.xx", sig=func(int)bool)

Fn7: {
@extern("file1.xx",sig=func(int)int)
@test("file1.xx",sig=func(int)int)
_
} @extern("file1.xx", sig=func(int)bool)
} @test("file1.xx", sig=func(int)bool)

-- non_ident.cue --
@extern("test")

package foo


"a-b": _ @extern("file1.xx",sig=func(int)int)
"a-b": _ @test("file1.xx",sig=func(int)int)

[string]: _ @extern("file1.xx",sig=func(int)int)
[string]: _ @test("file1.xx",sig=func(int)int)

-- late_extern.cue --
package foo

@extern("test")


Foo: _ @extern(file1.xx, abi=c, sig="func(int)int")
Foo: _ @test(file1.xx, abi=c, sig="func(int)int")

-- out/extern --
only one file-level extern attribute allowed per file:
./double_extern_a.cue:2:1
only one file-level extern attribute allowed per file:
./double_extern_b.cue:2:1
duplicate extern attributes:
./duplicate.cue:6:45
duplicate extern attributes:
duplicate @test attributes:
./duplicate.cue:6:43
duplicate @test attributes:
./duplicate.cue:11:3
interpreter name must be non-empty:
./empty_extern.cue:1:1
Expand All @@ -105,7 +105,7 @@ can only define functions for fields with identifier names, found "a-b":
./non_ident.cue:6:10
can only define functions for fields with identifier names, found [string]:
./non_ident.cue:8:13
extern attribute not associated with field:
@test attribute not associated with field:
./package_attr.cue:5:1
no interpreter defined for "wazem":
./unknown_interpreter.cue:1:1
2 changes: 1 addition & 1 deletion internal/core/runtime/testdata/failinit.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
package failinit


foo: _ @extern("file.xx")
foo: _ @test("file.xx")

-- out/extern --
TEST: fail initialization
30 changes: 30 additions & 0 deletions internal/core/runtime/testdata/legacy.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- cue.mod/modules.cue --
-- file1.cue --
@extern("test")

package foo


Foo: _ @extern(file1.xx, abi=c, sig="func(int)int")

Rename: _ @extern(file1.xx, name=Emaner, abi=c, sig="func(int)int")

-- file2.cue --
@extern("test")

package foo


Bar: {
@other()
@extern(file2.xx, abi=c, sig="func(int)int")
_
}

-- extern/out --
-- out/extern --
{
Foo: implFoo1
Bar: implBar2
Rename: implEmaner1
}
6 changes: 3 additions & 3 deletions internal/core/runtime/testdata/nested.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
package foo


a: Foo: _ @extern(file1.xx, abi=c, sig="func(int)int")
a: Foo: _ @test(file1.xx, abi=c, sig="func(int)int")

a: Rename: _ @extern(file1.xx, name=Emaner, abi=c, sig="func(int)int")
a: Rename: _ @test(file1.xx, name=Emaner, abi=c, sig="func(int)int")

-- file2.cue --
@extern("test")
Expand All @@ -17,7 +17,7 @@ package foo

a: foo: Bar: {
@other()
@extern(file2.xx, abi=c, sig="func(int)int")
@test(file2.xx, abi=c, sig="func(int)int")
_
}

Expand Down
2 changes: 1 addition & 1 deletion internal/core/runtime/testdata/no_top_extern.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
package foo


Foo: _ @extern(file.xx, abi=c, sig="func(int)int")
Foo: _ @test(file.xx, abi=c, sig="func(int)int")

-- extern/out --
-- out/extern/config --
Expand Down

0 comments on commit b70e543

Please sign in to comment.