Skip to content
Closed
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
43 changes: 39 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ define tables_generate
$(1) generate --lang cpp --out $(2)/a2 test/tables/A2.schema
$(1) generate --lang cpp --out $(2)/w1 test/tables/W1.schema
$(1) generate --lang cpp --out $(2)/w2 test/tables/W2.schema
$(1) generate --lang cpp --out $(2)/r1 test/tables/R1.schema
$(1) generate --lang cpp --out $(2)/r2 test/tables/R2.schema
$(1) generate --lang cpp --out $(2)/scalars tables/scalars
$(1) generate --lang cpp --out $(2)/maps tables/maps
$(1) generate --lang cpp --out $(2)/lists tables/lists
Expand All @@ -146,9 +148,9 @@ endef

tables_includes = -I$(1)/examples -I$(1)/pointers -I$(1)/block -I$(1)/blockhome -Itest/tables \
-I$(1)/v1 -I$(1)/v2 -I$(1)/p1 -I$(1)/p2 -I$(1)/p3 -I$(1)/jsonkeys \
-I$(1)/messages -I$(1)/stream -I$(1)/blobs -I$(1)/m1 -I$(1)/m2 -I$(1)/a1 -I$(1)/a2 -I$(1)/g1 -I$(1)/k1 -I$(1)/k2 -I$(1)/w1 -I$(1)/w2 -I$(1)/scalars -I$(1)/scalars2 -I$(1)/maps -I$(1)/lists -I$(1)/backend -I$(1)/vocab -I$(SERIALIZE)
-I$(1)/messages -I$(1)/stream -I$(1)/blobs -I$(1)/m1 -I$(1)/m2 -I$(1)/a1 -I$(1)/a2 -I$(1)/g1 -I$(1)/k1 -I$(1)/k2 -I$(1)/w1 -I$(1)/w2 -I$(1)/r1 -I$(1)/r2 -I$(1)/scalars -I$(1)/scalars2 -I$(1)/maps -I$(1)/lists -I$(1)/backend -I$(1)/vocab -I$(SERIALIZE)

build/tables-generated/.stamp: bin/schema $(SCHEMAS_TABLES) $(SCHEMAS_TABLES_POINTERS) $(SCHEMAS_TABLES_BLOCK) $(SCHEMAS_TABLES_MESSAGES) $(SCHEMAS_TABLES_BLOBS) $(SCHEMAS_TABLES_SCALARS) $(SCHEMAS_TABLES_MAPS) $(SCHEMAS_TABLES_LISTS) $(SCHEMAS_TABLES_BACKEND) $(SCHEMAS_TABLES_VOCAB) test/tables/V1.schema test/tables/V2.schema test/tables/P1.schema test/tables/P2.schema test/tables/P3.schema test/tables/JsonKeys.schema test/tables/M1.schema test/tables/M2.schema test/tables/A1.schema test/tables/A2.schema test/tables/G1.schema test/tables/K1.schema test/tables/K2.schema test/tables/W1.schema test/tables/W2.schema test/tables/Scalars2.schema
build/tables-generated/.stamp: bin/schema $(SCHEMAS_TABLES) $(SCHEMAS_TABLES_POINTERS) $(SCHEMAS_TABLES_BLOCK) $(SCHEMAS_TABLES_MESSAGES) $(SCHEMAS_TABLES_BLOBS) $(SCHEMAS_TABLES_SCALARS) $(SCHEMAS_TABLES_MAPS) $(SCHEMAS_TABLES_LISTS) $(SCHEMAS_TABLES_BACKEND) $(SCHEMAS_TABLES_VOCAB) test/tables/V1.schema test/tables/V2.schema test/tables/P1.schema test/tables/P2.schema test/tables/P3.schema test/tables/JsonKeys.schema test/tables/M1.schema test/tables/M2.schema test/tables/A1.schema test/tables/A2.schema test/tables/G1.schema test/tables/K1.schema test/tables/K2.schema test/tables/W1.schema test/tables/W2.schema test/tables/R1.schema test/tables/R2.schema test/tables/Scalars2.schema
@mkdir -p build/tables-generated
$(call tables_generate,./bin/schema,build/tables-generated)
@touch $@
Expand Down Expand Up @@ -1975,7 +1977,7 @@ wide-utf8-read-negative-control:
projection-union-arm-order-negative-control:
@mkdir -p build
@sed -E -e 's|" variant %d name=%s payload=|" variant %d payload=|' \
-e 's|i\+1, v\.Name, v\.Type\)|i+1, v.Type) // SABOTAGED: the arm names removed|' \
-e 's|i\+1, v\.WireName\(\), v\.Type\)|i+1, v.Type) // SABOTAGED: the arm names removed|' \
ir/projection.go > build/projection-no-arm-names.gotext
@grep -q SABOTAGED build/projection-no-arm-names.gotext || \
{ echo "NEGATIVE CONTROL FAILED: the sabotage did not remove the arm names"; exit 1; }
Expand Down Expand Up @@ -2456,6 +2458,7 @@ test: build/schema_test build/schema_test_guard build/schema_test_tables build/s
$(MAKE) tables-flat-wire
$(MAKE) tables-flat-wire-negative-control
$(MAKE) tables-was-negative-control
$(MAKE) tables-wasrows-negative-control
$(MAKE) tables-shared-node-negative-control
$(MAKE) tables-keyed-iteration-negative-control
$(MAKE) tables-hooks
Expand Down Expand Up @@ -3113,9 +3116,10 @@ CONFORMANCE_INCLUDES := -Ibuild/tables-generated/examples -Ibuild/tables-generat
-Ibuild/tables-generated/v2 -Ibuild/tables-generated/p1 -Ibuild/tables-generated/p3 \
-Ibuild/tables-generated/block -Ibuild/tables-generated/pointers \
-Ibuild/tables-generated/p2 -Ibuild/tables-generated/messages -Ibuild/tables-generated/stream \
-Ibuild/tables-generated/m1 -Ibuild/tables-generated/m2 -Ibuild/tables-generated/a1 -Ibuild/tables-generated/a2 -Ibuild/tables-generated/g1 -Ibuild/tables-generated/k1 -Ibuild/tables-generated/k2 -Ibuild/tables-generated/w1 -Ibuild/tables-generated/w2 -Ibuild/tables-generated/blobs -Itest/tables -Ibuild/tables-generated/scalars -Ibuild/tables-generated/scalars2 -Ibuild/tables-generated/backend -Ibuild/tables-generated/vocab -I$(SERIALIZE)
-Ibuild/tables-generated/m1 -Ibuild/tables-generated/m2 -Ibuild/tables-generated/a1 -Ibuild/tables-generated/a2 -Ibuild/tables-generated/g1 -Ibuild/tables-generated/k1 -Ibuild/tables-generated/k2 -Ibuild/tables-generated/w1 -Ibuild/tables-generated/w2 -Ibuild/tables-generated/r1 -Ibuild/tables-generated/r2 -Ibuild/tables-generated/blobs -Itest/tables -Ibuild/tables-generated/scalars -Ibuild/tables-generated/scalars2 -Ibuild/tables-generated/backend -Ibuild/tables-generated/vocab -I$(SERIALIZE)
CONFORMANCE_SOURCES = build/tables-generated/examples/TablesTable.cpp \
build/tables-generated/w1/W1Table.cpp build/tables-generated/w2/W2Table.cpp \
build/tables-generated/r1/R1Table.cpp build/tables-generated/r2/R2Table.cpp \
build/tables-generated/scalars/ScalarsTable.cpp build/tables-generated/scalars2/Scalars2Table.cpp \
build/tables-generated/examples/WideTable.cpp build/tables-generated/examples/NestedTable.cpp \
build/tables-generated/examples/KeyedTable.cpp build/tables-generated/examples/PackTable.cpp build/tables-generated/v1/V1Table.cpp \
Expand Down Expand Up @@ -3670,3 +3674,34 @@ tables-was-negative-control: build/tables-generated/.stamp test/tables/was_contr
@grep -q '^unknown=2 kind_mismatch=0 malformed=0 flagship=null escorts=2 home_name=untitled$$' build/tables-was-nc/without-was.log || \
{ echo "NEGATIVE CONTROL FAILED: without was, the W1 fleet did not read as unknown records under W2"; exit 1; }
@echo "negative control: stripping was from the renamed table turns the cross read RED (unknown counted, the pointers null, the value at its default)"

# THE VOCABULARY `was` CONTROL (docs/SPEC-TABLES.md §5). R1's config, whose
# enum value, union arm, keyed slot and nested type field ride under the
# hashes of Silver, ward, Silver and multiplier, read under R2, where each is
# renamed under `was`. The control strips the four attributes from R2 in a
# build copy, regenerates that unit with the SHIPPED compiler, and reads the
# same golden through the same program: the value reads None, the union
# reads None, the slot is dropped, the field holds its default, and `unknown`
# counts five: the value, the array element that carries the same value, the
# slot, the arm and the field. The positive half runs first, against the
# shipped R2.
.PHONY: tables-wasrows-negative-control
tables-wasrows-negative-control: build/tables-generated/.stamp test/tables/wasrows_control_main.cpp
@mkdir -p build/tables-wasrows-nc
$(CXX) $(TABLES_CXXFLAGS) -Ibuild/tables-generated/r2 -I$(SERIALIZE) test/tables/wasrows_control_main.cpp \
build/tables-generated/r2/R2Table.cpp -o build/tables-wasrows-nc/with-was
@./build/tables-wasrows-nc/with-was > build/tables-wasrows-nc/with-was.log
@cat build/tables-wasrows-nc/with-was.log
@grep -q '^unknown=0 kind_mismatch=0 malformed=0 grade=Argent effect=shield charge=2.5 mult=1.5 tally_argent=7$$' build/tables-wasrows-nc/with-was.log || \
{ echo "CONTROL FAILED: with was, the R1 config did not read in silence under R2"; exit 1; }
@sed -e 's/^\( [A-Z][A-Za-z]*\) | was = "[A-Za-z]*"$$/\1,/' -e 's/ *| was = "[A-Za-z]*"$$//' test/tables/R2.schema > build/tables-wasrows-nc/R2.schema
@test $$(grep -c 'was' build/tables-wasrows-nc/R2.schema) -eq $$(grep -c 'was' test/tables/R2.schema | awk '{print $$1 - 4}') || \
{ echo "NEGATIVE CONTROL: the was sabotage did not strip exactly four attributes"; exit 1; }
@rm -rf build/tables-wasrows-nc/r2 && ./bin/schema generate --lang cpp --out build/tables-wasrows-nc/r2 build/tables-wasrows-nc/R2.schema
$(CXX) $(TABLES_CXXFLAGS) -Ibuild/tables-wasrows-nc/r2 -I$(SERIALIZE) test/tables/wasrows_control_main.cpp \
build/tables-wasrows-nc/r2/R2Table.cpp -o build/tables-wasrows-nc/without-was
@./build/tables-wasrows-nc/without-was > build/tables-wasrows-nc/without-was.log
@cat build/tables-wasrows-nc/without-was.log
@grep -q '^unknown=5 kind_mismatch=0 malformed=0 grade=None effect=None charge=0 mult=1 tally_argent=0$$' build/tables-wasrows-nc/without-was.log || \
{ echo "NEGATIVE CONTROL FAILED: without was, the R1 config did not read as unknown names under R2"; exit 1; }
@echo "negative control: stripping was from the variant, the arms and the type's field turns the cross read RED (unknown counted, the value at its default)"
3 changes: 3 additions & 0 deletions compiler/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ func refuseUnported(u *ir.Unit, target string) error {
if err := refuseValueDefaults(u, target); err != nil {
return err
}
if err := refuseWasRows(u, target); err != nil {
return err
}
if err := refuseTableArms(u, target); err != nil {
return err
}
Expand Down
30 changes: 30 additions & 0 deletions compiler/wasrows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// The `was` ROWS' cross-target refusal (docs/SPEC-TABLES.md §5): a `was` on an
// enum variant, on a union arm, or on a field of a `type` a table reaches is
// carried by the C++ reference and the tool, and every other target names the
// follow-on rather than hashing the declared name where the wire carries the
// alias. [refuseUnported] reaches it for every port. A `was` on a TABLE's own
// field is every port's already, and a `was` on a table declaration names a
// node type id the ports' fixed class never writes.
package compiler

import (
"fmt"

"github.com/mas-bandwidth/schema/v2/ir"
)

// wasRowTargets is the canonical name of every built-in target whose backends
// carry the three; refuseWasRows names them.
var wasRowTargets = []string{"cpp"}

// refuseWasRows is the named refusal every target without the form gives a
// unit whose table closure carries a variant, arm or type-field `was`.
func refuseWasRows(u *ir.Unit, target string) error {
names := ir.WasRows(u)
if len(names) == 0 {
return nil
}
carry, flags := carriers(wasRowTargets)
return fmt.Errorf("unit declares was on an enum variant, a union arm or a type's field (%s): the three are %s only today, and the %s form is a named follow-on; generate with %s (docs/SPEC-TABLES.md §5)",
englishList(names), englishList(carry), target, englishList(flags))
}
78 changes: 78 additions & 0 deletions compiler/wasrows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// A `was` on an enum variant, a union arm or a type's field (docs/SPEC-TABLES.md
// §5) is C++'s today: the reference carries it, and every other target refuses
// the unit by name.
package compiler

import (
"fmt"
"strings"
"testing"

"github.com/mas-bandwidth/schema/v2/ir"
)

const wasRowsUnit = `package wrows

enum Grade
{
Bronze,
Argent | was = "Silver"
Gold
}

type Buff
{
mult float32 = 1.0 | was = "multiplier"
}

type Ward
{
charge float32 = 0.0
}

union Effect
{
shield Ward | was = "ward"
pong | was = "ping"
count int32
}

table Cfg
{
grade Grade
effect Effect
buff Buff
}
`

func TestWasRowsAreCppOnly(t *testing.T) {
u := unitFromSource(t, wasRowsUnit)
c := New()
for _, target := range c.Targets() {
out, err := c.Generate(u, target, Options{})
if target == "cpp" {
if err != nil {
t.Fatalf("cpp carries the was rows and refused: %v", err)
}
var all strings.Builder
for _, b := range out {
all.Write(b)
}
// every id the renamed things ride under is the OLD name's hash
for _, old := range []string{"Silver", "ward", "ping", "multiplier"} {
want := fmt.Sprintf("0x%016xull", ir.TableWireId(old))
if !strings.Contains(all.String(), want) {
t.Errorf("cpp output lacks the id of %q, %s", old, want)
}
}
continue
}
if err == nil {
t.Errorf("%s emitted a unit with variant, arm and type-field was instead of refusing it", target)
continue
}
if !strings.Contains(err.Error(), "Buff.mult, Effect.pong, Effect.shield and Grade.Argent") || !strings.Contains(err.Error(), "--lang cpp") {
t.Errorf("%s refused without naming the rows and the carrier: %v", target, err)
}
}
}
Loading
Loading