diff --git a/circuits/language.circom b/circuits/language.circom index 3aced66..2a30a8e 100644 --- a/circuits/language.circom +++ b/circuits/language.circom @@ -30,7 +30,6 @@ template Syntax() { template Command() { // STATE = [read_write_value, parsing_string, parsing_number] - signal output NOTHING[3] <== [0, 0, -1 ]; // Command returned by switch if we want to do nothing, e.g. read a whitespace char while looking for a key signal output START_BRACE[3] <== [1, 0, 0 ]; // Command returned by switch if we hit a start brace `{` signal output END_BRACE[3] <== [-1, 0, -1 ]; // Command returned by switch if we hit a end brace `}` signal output START_BRACKET[3] <== [2, 0, 0 ]; // Command returned by switch if we hit a start bracket `[` diff --git a/circuits/parser.circom b/circuits/parser.circom index 068cb46..b7dcac6 100644 --- a/circuits/parser.circom +++ b/circuits/parser.circom @@ -87,6 +87,8 @@ template StateUpdate(MAX_STACK_HEIGHT) { // * read in a quote `"` * component readQuote = IsEqual(); readQuote.in <== [byte, Syntax.QUOTE]; + component readOther = IsZero(); + readOther.in <== readDelimeter + readNumber.out + readQuote.out; //--------------------------------------------------------------------------------------------// // Yield instruction based on what byte we read * component readStartBraceInstruction = ScalarArrayMul(3); @@ -130,7 +132,7 @@ template StateUpdate(MAX_STACK_HEIGHT) { // * multiply the mask array elementwise with the instruction array * component mulMaskAndOut = ArrayMul(3); mulMaskAndOut.lhs <== mask.out; - mulMaskAndOut.rhs <== Instruction.out; + mulMaskAndOut.rhs <== [Instruction.out[0], Instruction.out[1], Instruction.out[2] - readOther.out]; // * compute the new stack * component newStack = RewriteStack(MAX_STACK_HEIGHT); newStack.stack <== stack; diff --git a/circuits/test/parser/values.test.ts b/circuits/test/parser/values.test.ts index eb1c1f3..7b6bd9f 100644 --- a/circuits/test/parser/values.test.ts +++ b/circuits/test/parser/values.test.ts @@ -22,52 +22,85 @@ describe("StateUpdate :: Values", () => { }); } - //-TEST_1----------------------------------------------------------// - // idea: Read a number value after a key in an object. - // state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]] - // read: `0` - // expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]] - // parsing_number --> 1 - let read_number = { ...INITIAL_IN }; - read_number.stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; - read_number.byte = Numbers.ZERO; - let read_number_out = { ...INITIAL_OUT }; - read_number_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; - read_number_out.next_parsing_number = 1; - generatePassCase(read_number, read_number_out, ">>>> `0` read"); + describe("StateUpdate :: Values :: Number", () => { + //-TEST_1----------------------------------------------------------// + // idea: Read a number value after a key in an object. + // state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]] + // read: `0` + // expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]] + // parsing_number --> 1 + let read_number = { ...INITIAL_IN }; + read_number.stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + read_number.byte = Numbers.ZERO; + let read_number_out = { ...INITIAL_OUT }; + read_number_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + read_number_out.next_parsing_number = 1; + generatePassCase(read_number, read_number_out, ">>>> `0` read"); - // // TODO: Note that reading a space while reading a number will not throw an error! + // // TODO: Note that reading a space while reading a number will not throw an error! - //-TEST_2----------------------------------------------------------// - // idea: Inside a number value after a key in an object. - // state: pointer == 2, stack == [1,3,0,0], parsing_number == 1 - // read: `1` - // expect: pointer --> 2 - // stack --> [1,3,0,0] - // parsing_number --> 0 - let inside_number_continue = { ...INITIAL_IN }; - inside_number_continue.stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; - inside_number_continue.parsing_number = 1; - inside_number_continue.byte = Numbers.ONE; - let inside_number_continue_out = { ...INITIAL_OUT }; - inside_number_continue_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; - inside_number_continue_out.next_parsing_number = 1; - generatePassCase(inside_number_continue, inside_number_continue_out, ">>>> `1` read"); + //-TEST_2----------------------------------------------------------// + // idea: Inside a number value after a key in an object. + // state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]], parsing_number == 1 + // read: `1` + // expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]] + // parsing_number --> 0 + let inside_number_continue = { ...INITIAL_IN }; + inside_number_continue.stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + inside_number_continue.parsing_number = 1; + inside_number_continue.byte = Numbers.ONE; + let inside_number_continue_out = { ...INITIAL_OUT }; + inside_number_continue_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + inside_number_continue_out.next_parsing_number = 1; + generatePassCase(inside_number_continue, inside_number_continue_out, ">>>> `1` read"); - //-TEST_3----------------------------------------------------------// - // idea: Inside a string key inside an object - // state: stack == [[1, 0], [0, 0], [0, 0], [0, 0]], parsing_string == 1 - // read: `,` - // expect: stack --> [[1, 0], [0, 0], [0, 0], [0, 0]] - // parsing_string --> 0 - let inside_number = { ...INITIAL_IN }; - inside_number.stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; - inside_number.parsing_string = 1; - inside_number.byte = Delimiters.COMMA; - let inside_number_out = { ...INITIAL_OUT }; - inside_number_out.next_stack = [[1, 0], [0, 0], [0, 0], [0, 0]]; - inside_number_out.next_parsing_string = 1; - generatePassCase(inside_number, inside_number_out, ">>>> `,` read"); + //-TEST_2----------------------------------------------------------// + // idea: Inside a number value after a key in an object. + // state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]], parsing_number == 1 + // read: `1` + // expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]] + // parsing_number --> 0 + let inside_number_exit = { ...INITIAL_IN }; + inside_number_exit.stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + inside_number_exit.parsing_number = 1; + inside_number_exit.byte = WhiteSpace.SPACE; + let inside_number_exit_out = { ...INITIAL_OUT }; + inside_number_exit_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + inside_number_exit_out.next_parsing_number = 0; + generatePassCase(inside_number_exit, inside_number_exit_out, ">>>> ` ` read"); + + //-TEST_3----------------------------------------------------------// + // idea: Inside a number value after a key in an object. + // state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]], parsing_number == 1 + // read: `$` + // expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]] + // parsing_number --> 0 + let inside_number_exit2 = { ...INITIAL_IN }; + inside_number_exit2.stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + inside_number_exit2.parsing_number = 1; + inside_number_exit2.byte = 36; // Dollar sign `$` + let inside_number_exit2_out = { ...INITIAL_OUT }; + inside_number_exit2_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + inside_number_exit2_out.next_parsing_number = 0; + generatePassCase(inside_number_exit2, inside_number_exit2_out, ">>>> `$` read"); + }); + + describe("StateUpdate :: Values :: String", () => { + //-TEST_4----------------------------------------------------------// + // idea: Inside a string key inside an object + // state: stack == [[1, 0], [0, 0], [0, 0], [0, 0]], parsing_string == 1 + // read: `,` + // expect: stack --> [[1, 0], [0, 0], [0, 0], [0, 0]] + // parsing_string --> 0 + let inside_number = { ...INITIAL_IN }; + inside_number.stack = [[1, 1], [0, 0], [0, 0], [0, 0]]; + inside_number.parsing_string = 1; + inside_number.byte = Delimiters.COMMA; + let inside_number_out = { ...INITIAL_OUT }; + inside_number_out.next_stack = [[1, 0], [0, 0], [0, 0], [0, 0]]; + inside_number_out.next_parsing_string = 1; + generatePassCase(inside_number, inside_number_out, ">>>> `,` read"); + }); describe("StateUpdate :: Values :: Array", () => { // Internal array parsing -----------------------------------------//