diff --git a/bin/build.js b/bin/build.js index f33b0c2..710bbfb 100755 --- a/bin/build.js +++ b/bin/build.js @@ -54,15 +54,13 @@ const generate = cb => { varSizeSpan, varIdSpan, varNameSpan, idSpan, commandSpan, - timeSpan, - vectorSpan + timeSpan } = ` scopeIdentifierSpan varSizeSpan varIdSpan varNameSpan idSpan commandSpan timeSpan - vectorSpan ` .trim().split(/\s+/) .reduce((res, n) => Object.assign(res, {[n]: p.span(p.code.span(n))}), {}); @@ -78,7 +76,9 @@ const generate = cb => { inDeclaration, simulation, inSimulation, - simulationTime, simulationVector, simulationId + simulationTime, + simulationVector, simulationVectorEnd, + simulationId } = ` declaration scopeType scopeTypeEnd @@ -90,7 +90,9 @@ const generate = cb => { inDeclaration simulation inSimulation - simulationTime simulationVector simulationId + simulationTime + simulationVector simulationVectorEnd + simulationId ` .trim().split(/\s+/) .reduce((res, n) => Object.assign(res, {[n]: p.node(n)}), {}); @@ -220,7 +222,7 @@ const generate = cb => { .select(cmd('0 1 x X Z'), p.invoke(p.code.store('command'), idSpan.start(simulationId))) .select(cmd('b B r R'), - p.invoke(p.code.store('command'), vectorSpan.start(simulationVector))) + p.invoke(p.code.store('command'), simulationVector)) .otherwise(p.error(4, 'Expected simulation command')); inSimulation @@ -231,9 +233,22 @@ const generate = cb => { .match(spaces, timeSpan.end(simulation)) .skipTo(simulationTime); + const onDigit = p.code.mulAdd('value', {base: 2, signed: false}); + simulationVector - .match(spaces, vectorSpan.end(idSpan.start(simulationId))) - .skipTo(simulationVector); + .select( + {0: 0, 1: 1, x: 2, z: 3}, + p.invoke( + onDigit, + {1: p.error(1, 'Content-Length overflow')}, + simulationVector + ) + ) + .otherwise(simulationVectorEnd); + + simulationVectorEnd + .match(spaces, idSpan.start(simulationId)) + .skipTo(simulationVectorEnd); simulationId .match(spaces, idSpan.end(simulation)) diff --git a/vcd_spans.c b/vcd_spans.c index dcd7657..ff1f9af 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -125,6 +125,8 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end value = 1; mask = 0; } + state->value = 0; + state->mask = 0; napi_value undefined, eventName, aTime, aCommand, aValue, aMask, return_val; ASSERT(undefined, napi_get_undefined(env, &undefined)) ASSERT(eventName, napi_create_string_latin1(env, (char*)p, (endp - p - 1), &eventName)) @@ -138,10 +140,29 @@ int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* end return 0; } -int vectorSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { - // TODO implement proper 4-state parser - state->value = strtoul((const char *)p, (char **)&endp, 2); - state->mask = 0; +int onDigit( + vcd_parser_t* state, + const unsigned char* p, + const unsigned char* endp, + int match +) { + state->value *= 2; + state->mask *= 2; + switch (match) { + case 1: { + state->value += 1; + return 0; + } + case 2: { + state->mask += 1; + return 0; + } + case 3: { + state->value += 1; + state->mask += 1; + return 0; + } + } return 0; }