Skip to content

Commit

Permalink
optimize scope=given execution by omitting other zencode
Browse files Browse the repository at this point in the history
optimize scope=given by disabling When/Then/etc. function handles

no need to process Then when scope=given

on introspection only the Given block is executed and the CODEC is
printed, please note the structure is named uppercase: "CODEC"

includes a small optimization to zencoed parser for comments

add scope test to meson tests
  • Loading branch information
jaromil committed Nov 12, 2023
1 parent d6d7d4e commit 3dfd69d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 54 deletions.
2 changes: 1 addition & 1 deletion bindings/javascript/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export const zencode_valid_input = async (
export const introspect = async (zencode, props?: ZenroomProps) => {
try {
const { result } = await zencode_valid_input(zencode, props);
return JSON.parse(result).codec;
return JSON.parse(result).CODEC;
} catch ({ logs }) {
console.error(logs);
const heap = JSON.parse(logs)
Expand Down
2 changes: 1 addition & 1 deletion build/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ tests = [
'generic_dilithium', 'generic_ecdh', 'generic_eddsa', 'generic_schnorr', 'given', 'hash',
'http', 'keys', 'kyber', 'ntrup', 'numbers', 'output', 'pack', 'parser', 'planetmint', 'pvss',
'random', 'reflow', 'rules', 'secshare', 'then', 'w3c', 'w3c_did', 'when',
'zencode_exec', 'zenswarm', 'zkp', 'zkp_multi_petitions', 'logfmt'
'zencode_exec', 'zenswarm', 'zkp', 'zkp_multi_petitions', 'logfmt', 'scope'
]
foreach test_suite : tests
test('zencode_'+test_suite.underscorify(),
Expand Down
123 changes: 76 additions & 47 deletions src/lua/zencode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,6 @@ function ZEN:begin(new_heap)
{name = 'enter_given', from = {'init', 'rule', 'scenario'}, to = 'given'},
{name = 'enter_given', from = {'given'}, to = 'given'},
{name = 'enter_and', from = 'given', to = 'given'},
{name = 'enter_then', from = {'given', 'when', 'then', 'endif', 'endforeach'}, to = 'then'},
{name = 'enter_and', from = 'then', to = 'then'},
}
if CONF.exec.scope == 'full' then
-- rule output given-only
Expand Down Expand Up @@ -395,7 +393,9 @@ function ZEN:begin(new_heap)
{name = 'enter_and', from = 'ifforeach', to = 'ifforeach'},
{name = 'enter_and', from = 'foreachif', to = 'foreachif'},
{name = 'enter_and', from = 'whenforeach', to = 'whenforeach'},
{name = 'enter_and', from = 'whenifforeach', to = 'whenifforeach'}
{name = 'enter_and', from = 'whenifforeach', to = 'whenifforeach'},
{name = 'enter_then', from = {'given', 'when', 'then', 'endif', 'endforeach'}, to = 'then'},
{name = 'enter_and', from = 'then', to = 'then'},
}
for _,v in pairs(extra_events) do table.insert(events, v) end
end
Expand All @@ -422,7 +422,7 @@ local function zencode_isempty(b)
end
end
local function zencode_iscomment(b)
local x <const> = string.char(b:byte(1))
local x <const> = string.sub(b,1,1) -- string.char(b:byte(1))
if x == '#' then
return true
else
Expand Down Expand Up @@ -641,26 +641,27 @@ function ZEN:run()
end
-- PRINT output
self:ftrace('--- Zencode execution completed')
if type(OUT) == 'table' then
self:ftrace('<<< Encoding { OUT } to JSON ')
-- this is all already encoded
-- needs to be formatted
-- was used CONF.output.format.fun
-- suspended until more formats are implemented
print( JSON.encode(OUT) )
self:ftrace('>>> Encoding successful')
else -- this should never occur in zencode, OUT is always a table
self:ftrace('<<< Printing OUT (plain format, not a table)')
print(OUT)
if CONF.exec.scope == 'full' then
if type(OUT) == 'table' then
self:ftrace('<<< Encoding { OUT } to JSON ')
-- this is all already encoded
-- needs to be formatted
-- was used CONF.output.format.fun
-- suspended until more formats are implemented
print( JSON.encode(OUT) )
self:ftrace('>>> Encoding successful')
else -- this should never occur in zencode, OUT is always a table
self:ftrace('<<< Printing OUT (plain format, not a table)')
print(OUT)
end
elseif CONF.exec.scope == 'given' then
print(JSON.encode({CODEC = CODEC}))
ZEN:debug() -- J64 HEAP and TRACE
end
end





---------------------------------------------------------------
-- ZENCODE PARSER
-------------------
-- ZENCODE WATCHDOG
-- assert all values in table are converted to zenroom types
-- used in zencode when transitioning out of given memory
function zenguard(val, key) -- AKA watchdog
Expand All @@ -671,8 +672,6 @@ function zenguard(val, key) -- AKA watchdog
return nil
end
end


-- compare heap.ACK and heap.CODEC
function ZEN:codecguard()
local left <const> = ACK
Expand All @@ -697,40 +696,70 @@ function ZEN:codecguard()
return true
end

-- the global ZEN context
------------------------------------------
-- ZENCODE STATEMENT DECLARATION FUNCTIONS
function Given(text, fn)
text = text:lower()
assert(not ZEN.given_steps[text], 'Conflicting GIVEN statement loaded by scenario: ' .. text, 2)
ZEN.given_steps[text] = fn
text = text:lower()
if ZEN.given_steps[text] then
error('Conflicting GIVEN statement loaded by scenario: ' .. text, 2)
end
ZEN.given_steps[text] = fn
end
function When(text, fn)
text = text:lower()
if ZEN.when_steps[text] then
error('Conflicting WHEN statement loaded by scenario: ' .. text, 2)
end
ZEN.when_steps[text] = fn
if ZENCODE_SCOPE == 'GIVEN' then
text = nil
fn = nil
else
text = text:lower()
if ZEN.when_steps[text] then
error('Conflicting WHEN statement loaded by scenario: ' .. text, 2)
end
ZEN.when_steps[text] = fn
end
end
function IfWhen(text, fn)
text = text:lower()
if ZEN.if_steps[text] then
error('Conflicting IF-WHEN statement loaded by scenario: ' .. text, 2)
end
if ZEN.when_steps[text] then
error('Conflicting IF-WHEN statement loaded by scenario: ' .. text, 2)
end
ZEN.if_steps[text] = fn
ZEN.when_steps[text] = fn
if ZENCODE_SCOPE == 'GIVEN' then
text = nil
fn = nil
else
text = text:lower()
if ZEN.if_steps[text] then
error('Conflicting IF-WHEN statement loaded by scenario: '..text, 2)
end
if ZEN.when_steps[text] then
error('Conflicting IF-WHEN statement loaded by scenario: '..text, 2)
end
ZEN.if_steps[text] = fn
ZEN.when_steps[text] = fn
end
end
function Foreach(text, fn)
text = text:lower()
assert(not ZEN.foreach_steps[text],'Conflicting FOREACH statement loaded by scenario: ' .. text, 2)
ZEN.foreach_steps[text] = fn
if ZENCODE_SCOPE == 'GIVEN' then
text = nil
fn = nil
else
text = text:lower()
if ZEN.foreach_steps[text] then
error('Conflicting FOREACH statement loaded by scenario: ' .. text, 2)
end
ZEN.foreach_steps[text] = fn
end
end
function Then(text, fn)
text = text:lower()
assert(not ZEN.then_steps[text],'Conflicting THEN statement loaded by scenario : ' .. text, 2)
ZEN.then_steps[text] = fn
if ZENCODE_SCOPE == 'GIVEN' then
text = nil
fn = nil
else
text = text:lower()
if ZEN.then_steps[text] then
error('Conflicting THEN statement loaded by scenario : ' .. text, 2)
end
ZEN.then_steps[text] = fn
end
end

---------------------------
-- ZENCODE GLOBAL UTILITIES
function Iam(name)
if name then
zencode_assert(not WHO, 'Identity already defined in WHO')
Expand Down
10 changes: 5 additions & 5 deletions test/zencode/scope.bats
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ When I create the random 'random'
Then print codec
EOF
save_output given_only_schema_output.json
assert_output '{"codec":{"keyring":{"encoding":"complex","name":"keyring","root":"Alice","schema":"keyring","zentype":"e"},"myFirstObject":{"encoding":"string","name":"myFirstObject","zentype":"d"},"mySecondObject":{"encoding":"string","name":"mySecondObject","zentype":"d"}}}'
assert_output '{"CODEC":{"keyring":{"encoding":"complex","name":"keyring","root":"Alice","schema":"keyring","zentype":"e"},"myFirstObject":{"encoding":"string","name":"myFirstObject","zentype":"d"},"mySecondObject":{"encoding":"string","name":"mySecondObject","zentype":"d"}}}'
}

@test "Zencode scope=given with missing element" {
Expand Down Expand Up @@ -71,7 +71,7 @@ When I create the random 'random'
Then print codec
EOF
save_output given_schema_missing.json
assert_output '{"codec":{"does_not_exists":{"encoding":"string","missing":true,"name":"does_not_exists","zentype":"e"},"myFirstObject":{"encoding":"string","name":"myFirstObject","zentype":"d"}}}'
assert_output '{"CODEC":{"does_not_exists":{"encoding":"string","missing":true,"name":"does_not_exists","zentype":"e"},"myFirstObject":{"encoding":"string","name":"myFirstObject","zentype":"d"}}}'
}

@test "Zencode scope=given with missing dictionary or array" {
Expand Down Expand Up @@ -100,7 +100,7 @@ and I have a 'base64 dictionary' named 'missingArray'
Then print codec
EOF
save_output given_schema_missing.json
assert_output '{"codec":{"missingArray":{"encoding":"base64","missing":true,"name":"missingArray","zentype":"d"},"missingDictionary":{"encoding":"string","missing":true,"name":"missingDictionary","zentype":"d"},"myArray":{"encoding":"string","name":"myArray","zentype":"a"},"myDictionary":{"encoding":"string","name":"myDictionary","zentype":"d"}}}'
assert_output '{"CODEC":{"missingArray":{"encoding":"base64","missing":true,"name":"missingArray","zentype":"d"},"missingDictionary":{"encoding":"string","missing":true,"name":"missingDictionary","zentype":"d"},"myArray":{"encoding":"string","name":"myArray","zentype":"a"},"myDictionary":{"encoding":"string","name":"myDictionary","zentype":"d"}}}'
}

@test "Zencode scope=given with missing schema type" {
Expand All @@ -125,7 +125,7 @@ and I have a 'keyring'
Then print codec
EOF
save_output given_schema_missing.json
assert_output '{"codec":{"ethereum_address":{"bintype":"zenroom.octet","encoding":"complex","name":"ethereum_address","schema":"ethereum_address","zentype":"e"},"keyring":{"encoding":"complex","name":"keyring","schema":"keyring","zentype":"e"},"missing_address":{"encoding":"complex","missing":true,"name":"missing_address","schema":"ethereum_address","zentype":"e"}}}'
assert_output '{"CODEC":{"ethereum_address":{"bintype":"zenroom.octet","encoding":"complex","name":"ethereum_address","schema":"ethereum_address","zentype":"e"},"keyring":{"encoding":"complex","name":"keyring","schema":"keyring","zentype":"e"},"missing_address":{"encoding":"complex","missing":true,"name":"missing_address","schema":"ethereum_address","zentype":"e"}}}'


# TODO: missing keyring
Expand Down Expand Up @@ -162,6 +162,6 @@ When I create the random 'random'
Then print codec
EOF
save_output given_schema_missing.json
assert_output '{"codec":{"does_not_exists":{"encoding":"string","missing":true,"name":"does_not_exists","root":"myFirstObject","zentype":"d"},"missing_public_key":{"encoding":"hex","missing":true,"name":"missing_public_key","root":"Alice","zentype":"e"},"myStringArray":{"encoding":"string","name":"myStringArray","root":"myFirstObject","zentype":"a"}}}'
assert_output '{"CODEC":{"does_not_exists":{"encoding":"string","missing":true,"name":"does_not_exists","root":"myFirstObject","zentype":"d"},"missing_public_key":{"encoding":"hex","missing":true,"name":"missing_public_key","root":"Alice","zentype":"e"},"myStringArray":{"encoding":"string","name":"myStringArray","root":"myFirstObject","zentype":"a"}}}'

}

0 comments on commit 3dfd69d

Please sign in to comment.