new way of handling scope/vars
This commit is contained in:
parent
f9d7687532
commit
5c5126c019
118
bin/build.js
118
bin/build.js
@ -58,13 +58,12 @@ const generate = (cb) => {
|
||||
Object.keys(properties).map(key => p.property(properties[key], key));
|
||||
|
||||
const {
|
||||
scopeIdentifierSpan,
|
||||
// scopeIdentifierSpan,
|
||||
varSizeSpan, varIdSpan, varNameSpan,
|
||||
idSpan,
|
||||
commandSpan,
|
||||
timeSpan
|
||||
} = `
|
||||
scopeIdentifierSpan
|
||||
varSizeSpan varIdSpan varNameSpan
|
||||
idSpan
|
||||
commandSpan
|
||||
@ -73,10 +72,12 @@ const generate = (cb) => {
|
||||
.trim().split(/\s+/)
|
||||
.reduce((res, n) => Object.assign(res, {[n]: p.span(p.code.span(n))}), {});
|
||||
|
||||
// scopeIdentifierSpan
|
||||
|
||||
const {
|
||||
declaration,
|
||||
scopeType, scopeTypeEnd,
|
||||
scopeIdentifier, scopeIdentifierEnd,
|
||||
// scopeType, scopeTypeEnd,
|
||||
// scopeIdentifier, scopeIdentifierEnd,
|
||||
varType, varTypeEnd,
|
||||
varSize, varSizeEnd,
|
||||
varId, varIdEnd,
|
||||
@ -89,8 +90,6 @@ const generate = (cb) => {
|
||||
simulationId
|
||||
} = `
|
||||
declaration
|
||||
scopeType scopeTypeEnd
|
||||
scopeIdentifier scopeIdentifierEnd
|
||||
varType varTypeEnd
|
||||
varSize varSizeEnd
|
||||
varId varIdEnd
|
||||
@ -105,6 +104,9 @@ const generate = (cb) => {
|
||||
.trim().split(/\s+/)
|
||||
.reduce((res, n) => Object.assign(res, {[n]: p.node(n)}), {});
|
||||
|
||||
// scopeType scopeTypeEnd
|
||||
// scopeIdentifier scopeIdentifierEnd
|
||||
|
||||
const enddefinitions = p.node('inDeclarationEnd');
|
||||
|
||||
const cmd = objection({
|
||||
@ -134,56 +136,50 @@ const generate = (cb) => {
|
||||
|
||||
declaration
|
||||
.match(spaces, declaration)
|
||||
.select(cmd('$scope'),
|
||||
p.invoke(p.code.store('command'), commandSpan.start(scopeType)))
|
||||
.select(cmd('$var'),
|
||||
p.invoke(p.code.store('command'), commandSpan.start(varType)))
|
||||
.select(cmd('$comment $date $timescale $upscope $version'),
|
||||
// .select(cmd('$scope'),
|
||||
// p.invoke(p.code.store('command'), commandSpan.start(scopeType)))
|
||||
// .select(cmd('$var'),
|
||||
// p.invoke(p.code.store('command'), commandSpan.start(varType)))
|
||||
.select(cmd('$scope $var $upscope $comment $date $timescale $version'),
|
||||
p.invoke(p.code.store('command'), commandSpan.start(inDeclaration)))
|
||||
.select(cmd('$enddefinitions'),
|
||||
p.invoke(p.code.store('command'), commandSpan.start(enddefinitions)))
|
||||
.otherwise(p.error(1, 'Expected declaration command'));
|
||||
|
||||
// $scope
|
||||
// $scope module clkdiv2n_tb $end
|
||||
// ^^^^^^
|
||||
|
||||
scopeType
|
||||
.match(spaces, scopeType)
|
||||
.otherwise(scopeTypeEnd);
|
||||
// scopeType.match(spaces, scopeType).otherwise(scopeTypeEnd);
|
||||
// scopeTypeEnd
|
||||
// .select(
|
||||
// {
|
||||
// module: 0,
|
||||
// task: 1,
|
||||
// function: 2,
|
||||
// begin: 3,
|
||||
// fork: 4,
|
||||
// // extra scopes from Verilator
|
||||
// generate: 5,
|
||||
// struct: 6,
|
||||
// union: 7,
|
||||
// class: 8,
|
||||
// interface: 9,
|
||||
// package: 10,
|
||||
// program: 11
|
||||
// },
|
||||
// p.invoke(p.code.store('type'), scopeIdentifier))
|
||||
// .otherwise(p.error(2, 'Expected scope type'));
|
||||
|
||||
scopeTypeEnd
|
||||
.select(
|
||||
{
|
||||
module: 0,
|
||||
task: 1,
|
||||
function: 2,
|
||||
begin: 3,
|
||||
fork: 4,
|
||||
// extra scopes from Verilator
|
||||
generate: 5,
|
||||
struct: 6,
|
||||
union: 7,
|
||||
class: 8,
|
||||
interface: 9,
|
||||
package: 10,
|
||||
program: 11
|
||||
},
|
||||
p.invoke(p.code.store('type'), scopeIdentifier))
|
||||
.otherwise(p.error(2, 'Expected scope type'));
|
||||
// $scope module clkdiv2n_tb $end
|
||||
// ^^^^^^^^^^^
|
||||
|
||||
scopeIdentifier
|
||||
.match(spaces, scopeIdentifier)
|
||||
.otherwise(scopeIdentifierSpan.start(scopeIdentifierEnd));
|
||||
// scopeIdentifier.match(spaces, scopeIdentifier).otherwise(scopeIdentifierSpan.start(scopeIdentifierEnd));
|
||||
// scopeIdentifierEnd.match(spaces, scopeIdentifierSpan.end(inDeclaration)).skipTo(scopeIdentifierEnd);
|
||||
|
||||
scopeIdentifierEnd
|
||||
.match(spaces, scopeIdentifierSpan.end(inDeclaration))
|
||||
.skipTo(scopeIdentifierEnd);
|
||||
|
||||
// $var
|
||||
|
||||
varType
|
||||
.match(spaces, varType)
|
||||
.otherwise(varTypeEnd);
|
||||
// $var reg 3 ( r_reg [2:0] $end
|
||||
// ^^^
|
||||
|
||||
varType.match(spaces, varType).otherwise(varTypeEnd);
|
||||
varTypeEnd
|
||||
.select({
|
||||
event: 1,
|
||||
@ -207,29 +203,23 @@ const generate = (cb) => {
|
||||
}, p.invoke(p.code.store('type'), varSize))
|
||||
.otherwise(p.error(3, 'Expected var type'));
|
||||
|
||||
varSize
|
||||
.match(spaces, varSize)
|
||||
.otherwise(varSizeSpan.start(varSizeEnd));
|
||||
// $var reg 3 ( r_reg [2:0] $end
|
||||
// ^
|
||||
|
||||
varSizeEnd
|
||||
.match(spaces, varSizeSpan.end(varId))
|
||||
.skipTo(varSizeEnd);
|
||||
varSize.match(spaces, varSize).otherwise(varSizeSpan.start(varSizeEnd));
|
||||
varSizeEnd.match(spaces, varSizeSpan.end(varId)).skipTo(varSizeEnd);
|
||||
|
||||
varId
|
||||
.match(spaces, varId)
|
||||
.otherwise(varIdSpan.start(varIdEnd));
|
||||
// $var reg 3 ( r_reg [2:0] $end
|
||||
// ^
|
||||
|
||||
varIdEnd
|
||||
.match(spaces, varIdSpan.end(varName))
|
||||
.skipTo(varIdEnd);
|
||||
varId.match(spaces, varId).otherwise(varIdSpan.start(varIdEnd));
|
||||
varIdEnd.match(spaces, varIdSpan.end(varName)).skipTo(varIdEnd);
|
||||
|
||||
varName
|
||||
.match(spaces, varName)
|
||||
.otherwise(varNameSpan.start(varNameEnd));
|
||||
// $var reg 3 ( r_reg [2:0] $end
|
||||
// ^^^^^
|
||||
|
||||
varNameEnd
|
||||
.match(spaces, varNameSpan.end(inDeclaration))
|
||||
.skipTo(varNameEnd);
|
||||
varName.match(spaces, varName).otherwise(varNameSpan.start(varNameEnd));
|
||||
varNameEnd.match('$end', commandSpan.end(varNameSpan.end(declaration))).skipTo(varNameEnd);
|
||||
|
||||
// $end
|
||||
|
||||
|
72
lib/command-handler.js
Normal file
72
lib/command-handler.js
Normal file
@ -0,0 +1,72 @@
|
||||
'use strict';
|
||||
|
||||
const handleScope = (info, str) => {
|
||||
const [type, name] = str.split(/\s+/);
|
||||
const ero = {kind: 'scope', type, name, body: []};
|
||||
const current = info.stack[info.stack.length - 1];
|
||||
current.body.push(ero);
|
||||
info.stack.push(ero);
|
||||
// console.log(ero);
|
||||
};
|
||||
|
||||
const handleUpScope = (info /* , str */) => {
|
||||
info.stack.pop();
|
||||
// console.log(['upscope', str]);
|
||||
};
|
||||
|
||||
const handleVar = (info, str) => {
|
||||
// reg 3 ( r_reg [2:0]
|
||||
// 0 1 2 3+
|
||||
const eroj = str.split(/\s+/);
|
||||
const ero = {
|
||||
kind: 'var',
|
||||
type: eroj[0],
|
||||
size: parseInt(eroj[1]),
|
||||
link: eroj[2],
|
||||
name: eroj.slice(3).join('')
|
||||
};
|
||||
{
|
||||
const m = ero.name.match('^(?<name>\\w+)\\[' + (ero.size - 1) + ':0]$');
|
||||
if (m) {
|
||||
ero.name = m.groups.name;
|
||||
}
|
||||
}
|
||||
const current = info.stack[info.stack.length - 1];
|
||||
current.body.push(ero);
|
||||
// console.log(ero);
|
||||
};
|
||||
|
||||
const commandHandler = (info, cmd, str) => {
|
||||
str = str.trim();
|
||||
switch(cmd) {
|
||||
case 1:
|
||||
info.comment = str;
|
||||
// console.log(['comment', str]);
|
||||
break;
|
||||
case 2:
|
||||
info.date = str;
|
||||
// console.log(['date', str]);
|
||||
break;
|
||||
case 3:
|
||||
handleScope(info, str);
|
||||
break;
|
||||
case 4:
|
||||
info.timescale = str;
|
||||
// console.log(['timescale', str]);
|
||||
break;
|
||||
case 5:
|
||||
handleUpScope(info, str);
|
||||
break;
|
||||
case 6:
|
||||
handleVar(info, str);
|
||||
break;
|
||||
case 7:
|
||||
info.version = str;
|
||||
// console.log(['version', str]);
|
||||
break;
|
||||
default:
|
||||
console.log([cmd, str]);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = commandHandler;
|
@ -5,6 +5,8 @@ const EventEmitter = require('events').EventEmitter;
|
||||
|
||||
const dotProp = require('dot-prop');
|
||||
|
||||
const commandHandler = require('./command-handler.js');
|
||||
|
||||
// function _waitForStart(mod) {
|
||||
// return new Promise((resolve)=>{
|
||||
// mod.addOnPostRun(resolve);
|
||||
@ -50,6 +52,7 @@ const bindCWrap = (c, wasm) => {
|
||||
};
|
||||
|
||||
const getWrapper = wasm => {
|
||||
// console.log(wasm);
|
||||
|
||||
const c = {};
|
||||
|
||||
@ -115,6 +118,7 @@ const getWrapper = wasm => {
|
||||
// console.log({name, time, command, valueWords});
|
||||
|
||||
|
||||
|
||||
// const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*8));
|
||||
// const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*8));
|
||||
|
||||
@ -159,8 +163,13 @@ const getWrapper = wasm => {
|
||||
break;
|
||||
// path to path (any type)
|
||||
case 3:
|
||||
tmp = dotProp.get(boundInfo, getString(v0, v1));
|
||||
// console.log(`for ${getString(v0, v1)} got ${tmp}, set to ${prop}`);
|
||||
tmp = getString(v0, v1)
|
||||
.split(',')
|
||||
.map(e => dotProp.get(boundInfo, e));
|
||||
if (tmp.length === 1) {
|
||||
dotProp.set(boundInfo, prop, tmp[0]);
|
||||
break;
|
||||
}
|
||||
dotProp.set(boundInfo, prop, tmp);
|
||||
break;
|
||||
// create empty object at path
|
||||
@ -168,7 +177,9 @@ const getWrapper = wasm => {
|
||||
// console.log(`${prop} is new {}`);
|
||||
dotProp.set(boundInfo, prop, {});
|
||||
break;
|
||||
|
||||
case 5:
|
||||
commandHandler(boundInfo, v0, prop);
|
||||
break;
|
||||
default: throw new Error();
|
||||
}
|
||||
|
||||
@ -221,9 +232,8 @@ module.exports = async wasm => {
|
||||
// console.log('getWrapper', lib);
|
||||
await lib.start();
|
||||
// console.log('vcd wasm srarted');
|
||||
|
||||
const wires = {};
|
||||
const info = {stack: [wires], wires: wires};
|
||||
const wires = {kind: 'scope', type: '.', name: '.', body: []};
|
||||
const info = {stack: [wires], wires};
|
||||
|
||||
const s = new stream.Writable();
|
||||
|
||||
@ -245,7 +255,7 @@ module.exports = async wasm => {
|
||||
const cxt = lib.init(lifemit, triemit, info);
|
||||
|
||||
s._write = function (chunk, encoding, callback) {
|
||||
// console.log(cxt, info);
|
||||
// console.log('chunk:', chunk.length);
|
||||
const err = lib.execute(cxt, lifemit, triemit2, info, chunk);
|
||||
if (err) {
|
||||
console.log(err);
|
||||
|
File diff suppressed because one or more lines are too long
BIN
out/vcd.wasm
BIN
out/vcd.wasm
Binary file not shown.
56
vcd_spans.c
56
vcd_spans.c
@ -77,41 +77,53 @@ int stringEq (
|
||||
}
|
||||
|
||||
int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||
|
||||
const uint8_t command = state->command;
|
||||
#ifndef VCDWASM
|
||||
napi_env env = state->napi_env;
|
||||
#endif
|
||||
|
||||
if (state->command == 5) { // $upscope
|
||||
state->stackPointer -= 1;
|
||||
return 0;
|
||||
}
|
||||
// if (command == 5) { // $upscope
|
||||
// state->stackPointer -= 1;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
if (
|
||||
(state->command == 1) || // $comment
|
||||
(state->command == 2) || // $date
|
||||
(state->command == 4) || // $timescale
|
||||
(state->command == 7) // $version
|
||||
(command == 1) || // $comment
|
||||
(command == 2) || // $date
|
||||
(command == 3) || // $scope
|
||||
(command == 4) || // $timescale
|
||||
(command == 5) || // $upscope
|
||||
(command == 6) || // $var
|
||||
(command == 7) // $version
|
||||
) {
|
||||
char* key;
|
||||
switch(state->command) {
|
||||
switch(command) {
|
||||
case 1: key = "comment"; break;
|
||||
case 2: key = "date"; break;
|
||||
case 4: key = "timescale"; break;
|
||||
// case 6: key = "var"; break;
|
||||
case 7: key = "version"; break;
|
||||
}
|
||||
#ifndef VCDWASM
|
||||
|
||||
napi_value val;
|
||||
ASSERT(val, napi_create_string_latin1(env, (char*)p, (endp - p - 4), &val))
|
||||
ASSERT(state->info, napi_set_named_property(env, state->info, key, val))
|
||||
#else
|
||||
strcopy(p, endp - 3, state->tmpStr);
|
||||
set_property_string(key, state->tmpStr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
if ((command > 0) && (command < 8)) {
|
||||
const int len = endp - p;
|
||||
int tailLen = 3;
|
||||
if (len < 4) {
|
||||
tailLen = len;
|
||||
}
|
||||
strcopy(p, endp - tailLen, state->tmpStr);
|
||||
// set_property_string(key, state->tmpStr);
|
||||
on_command(state->tmpStr, command);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (state->command == 8) { // $enddefinitions
|
||||
if (command == 8) { // $enddefinitions
|
||||
*(char *)state->idStr = 0;
|
||||
*(char *)state->timeStampStr = 0;
|
||||
#ifndef VCDWASM
|
||||
@ -167,7 +179,13 @@ int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsig
|
||||
}
|
||||
|
||||
int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||
state->size = strtol((const char *)p, (char **)&endp, 10);
|
||||
const int32_t size = strtol((const char *)p, (char **)&endp, 10);
|
||||
state->size = size;
|
||||
#ifndef VCDWASM
|
||||
#else
|
||||
set_property_int("varType", state->type);
|
||||
set_property_int("varSize", size);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -199,7 +217,7 @@ int varNameSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char
|
||||
// set
|
||||
// info.stack[sp].`tmpStr` = info.varId
|
||||
snprintf(state->tmpStr2, 4096, "stack.%d.%s", state->stackPointer, state->tmpStr);
|
||||
set_path_to_path(state->tmpStr2, "varId");
|
||||
set_path_to_path(state->tmpStr2, "varType,varSize,varId");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,6 +58,10 @@ void new_object_path(const char* name) {
|
||||
bound_set_property(name, strlen(name), 4, 0, 0);
|
||||
}
|
||||
|
||||
void on_command(const char* body, const int command) {
|
||||
bound_set_property(body, strlen(body), 5, command, 0);
|
||||
}
|
||||
|
||||
int get_property_int(const char* name) {
|
||||
return bound_get_property(name, strlen(name));
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ void set_property_string(const char* name, const char* value);
|
||||
void set_path_string(const char* name, const char* value);
|
||||
void set_path_to_path(const char* name, const char* value);
|
||||
void new_object_path(const char* name);
|
||||
void on_command(const char* body, const int command);
|
||||
int get_property_int(const char* name);
|
||||
void emit_lifee(const char* name);
|
||||
void emit_triee(
|
||||
|
Loading…
x
Reference in New Issue
Block a user