better API
This commit is contained in:
parent
31bca500a0
commit
fd06dc4104
76
bin/build.js
76
bin/build.js
@ -15,11 +15,14 @@ p.property('i32', 'size');
|
|||||||
p.property('i32', 'time');
|
p.property('i32', 'time');
|
||||||
p.property('ptr', 'trigger');
|
p.property('ptr', 'trigger');
|
||||||
p.property('ptr', 'info');
|
p.property('ptr', 'info');
|
||||||
p.property('ptr', 'emit');
|
p.property('ptr', 'triee');
|
||||||
|
p.property('ptr', 'lifee');
|
||||||
|
p.property('ptr', 'hier');
|
||||||
p.property('ptr', 'napi_env');
|
p.property('ptr', 'napi_env');
|
||||||
|
|
||||||
const scopeIdentifierSpan = p.span(p.code.span('scopeIdentifierSpan'));
|
const scopeIdentifierSpan = p.span(p.code.span('scopeIdentifierSpan'));
|
||||||
const varSizeSpan = p.span(p.code.span('varSizeSpan'));
|
const varSizeSpan = p.span(p.code.span('varSizeSpan'));
|
||||||
|
const varIdSpan = p.span(p.code.span('varIdSpan'));
|
||||||
const idSpan = p.span(p.code.span('idSpan'));
|
const idSpan = p.span(p.code.span('idSpan'));
|
||||||
const commandSpan = p.span(p.code.span('commandSpan'));
|
const commandSpan = p.span(p.code.span('commandSpan'));
|
||||||
const timeSpan = p.span(p.code.span('timeSpan'));
|
const timeSpan = p.span(p.code.span('timeSpan'));
|
||||||
@ -53,16 +56,42 @@ const simulationId = p.node('simulationId');
|
|||||||
|
|
||||||
const spaces = [' ', '\n', '\r', '\t'];
|
const spaces = [' ', '\n', '\r', '\t'];
|
||||||
|
|
||||||
|
const objection = lut => arg => arg.split(/\s+/).reduce((res, key) => {
|
||||||
|
if (lut[key] === undefined) {
|
||||||
|
throw new Error(key);
|
||||||
|
}
|
||||||
|
res[key] = lut[key];
|
||||||
|
return res;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const cmd = objection({
|
||||||
|
$comment: 1,
|
||||||
|
$date: 2,
|
||||||
|
$scope: 3,
|
||||||
|
$timescale: 4,
|
||||||
|
$upscope: 5,
|
||||||
|
$var: 6,
|
||||||
|
$version: 7,
|
||||||
|
$enddefinitions: 8,
|
||||||
|
$dumpall: 9,
|
||||||
|
$dumpoff: 10,
|
||||||
|
$dumpon: 11,
|
||||||
|
$dumpvars: 12,
|
||||||
|
'#': 13,
|
||||||
|
'0': 14, '1': 15, x: 16, X: 17, Z: 18,
|
||||||
|
b: 19, B: 20, r: 21, R: 22
|
||||||
|
});
|
||||||
|
|
||||||
declaration
|
declaration
|
||||||
.match(spaces, declaration)
|
.match(spaces, declaration)
|
||||||
.select({$scope: 3}, p.invoke(p.code.store('command'), commandSpan.start(scopeType)))
|
.select(cmd('$scope'),
|
||||||
.select({$var: 6}, p.invoke(p.code.store('command'), commandSpan.start(varType)))
|
p.invoke(p.code.store('command'), commandSpan.start(scopeType)))
|
||||||
.select({
|
.select(cmd('$var'),
|
||||||
$comment: 1, $date: 2, $timescale: 4, $upscope: 5, $version: 7
|
p.invoke(p.code.store('command'), commandSpan.start(varType)))
|
||||||
}, p.invoke(p.code.store('command'), commandSpan.start(inDeclaration)))
|
.select(cmd('$comment $date $timescale $upscope $version'),
|
||||||
.select({
|
p.invoke(p.code.store('command'), commandSpan.start(inDeclaration)))
|
||||||
$enddefinitions: 8
|
.select(cmd('$enddefinitions'),
|
||||||
}, p.invoke(p.code.store('command'), commandSpan.start(enddefinitions)))
|
p.invoke(p.code.store('command'), commandSpan.start(enddefinitions)))
|
||||||
.otherwise(p.error(1, 'Expected declaration command'));
|
.otherwise(p.error(1, 'Expected declaration command'));
|
||||||
|
|
||||||
// $scope
|
// $scope
|
||||||
@ -72,9 +101,8 @@ scopeType
|
|||||||
.otherwise(scopeTypeEnd);
|
.otherwise(scopeTypeEnd);
|
||||||
|
|
||||||
scopeTypeEnd
|
scopeTypeEnd
|
||||||
.select({
|
.select({begin: 1, fork: 2, function: 3, module: 4, task: 5},
|
||||||
begin: 1, fork: 2, function: 3, module: 4, task: 5
|
p.invoke(p.code.store('type'), scopeIdentifier))
|
||||||
}, p.invoke(p.code.store('type'), scopeIdentifier))
|
|
||||||
.otherwise(p.error(2, 'Expected scope type'));
|
.otherwise(p.error(2, 'Expected scope type'));
|
||||||
|
|
||||||
scopeIdentifier
|
scopeIdentifier
|
||||||
@ -124,10 +152,10 @@ varSizeEnd
|
|||||||
|
|
||||||
varId
|
varId
|
||||||
.match(spaces, varId)
|
.match(spaces, varId)
|
||||||
.otherwise(idSpan.start(varIdEnd));
|
.otherwise(varIdSpan.start(varIdEnd));
|
||||||
|
|
||||||
varIdEnd
|
varIdEnd
|
||||||
.match(spaces, idSpan.end(inDeclaration))
|
.match(spaces, varIdSpan.end(inDeclaration))
|
||||||
.skipTo(varIdEnd);
|
.skipTo(varIdEnd);
|
||||||
|
|
||||||
// $end
|
// $end
|
||||||
@ -142,18 +170,14 @@ enddefinitions
|
|||||||
|
|
||||||
simulation
|
simulation
|
||||||
.match([' ', '\n', '\t'], simulation)
|
.match([' ', '\n', '\t'], simulation)
|
||||||
.select({
|
.select(cmd('$dumpall $dumpoff $dumpon $dumpvars $comment'),
|
||||||
$dumpall: 9, $dumpoff: 10, $dumpon: 11, $dumpvars: 12, $comment: 1
|
p.invoke(p.code.store('command'), commandSpan.start(inSimulation)))
|
||||||
}, p.invoke(p.code.store('command'), commandSpan.start(inSimulation)))
|
.select(cmd('#'),
|
||||||
.select({
|
p.invoke(p.code.store('command'), timeSpan.start(simulationTime)))
|
||||||
'#': 13
|
.select(cmd('0 1 x X Z'),
|
||||||
}, p.invoke(p.code.store('command'), timeSpan.start(simulationTime)))
|
p.invoke(p.code.store('command'), idSpan.start(simulationId)))
|
||||||
.select({
|
.select(cmd('b B r R'),
|
||||||
'0': 14, '1': 15, x: 16, X: 17, Z: 18
|
p.invoke(p.code.store('command'), vectorSpan.start(simulationVector)))
|
||||||
}, p.invoke(p.code.store('command'), idSpan.start(simulationId)))
|
|
||||||
.select({
|
|
||||||
b: 19, B: 20, r: 21, R: 22
|
|
||||||
}, p.invoke(p.code.store('command'), vectorSpan.start(simulationVector)))
|
|
||||||
.otherwise(p.error(4, 'Expected simulation command'));
|
.otherwise(p.error(4, 'Expected simulation command'));
|
||||||
|
|
||||||
inSimulation
|
inSimulation
|
||||||
|
40
bin/find.js
40
bin/find.js
@ -1,54 +1,44 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const EventEmitter = require('events').EventEmitter;
|
|
||||||
|
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
|
||||||
const lib = require('../index.js');
|
const vcd = require('../index.js');
|
||||||
|
|
||||||
const dir = './tmp/';
|
const dir = './tmp/';
|
||||||
|
|
||||||
fs.readdir(dir).then(files => {
|
fs.readdir(dir).then(files => {
|
||||||
const tt0 = Date.now();
|
const tt0 = Date.now();
|
||||||
async.eachLimit(files, 1, (fileName, callback) => {
|
async.eachLimit(files, 1, (fileName, callback) => {
|
||||||
let len = 0;
|
|
||||||
let chunks = 0;
|
|
||||||
let goodChunks = 0;
|
|
||||||
let start = 0;
|
let start = 0;
|
||||||
let stop = 0;
|
let stop = 0;
|
||||||
const t0 = Date.now();
|
const t0 = Date.now();
|
||||||
|
|
||||||
const ee = new EventEmitter();
|
let inst = vcd();
|
||||||
|
|
||||||
const cxt = lib.init();
|
// inst.on('$enddefinitions', () => {
|
||||||
lib.setTrigger(cxt, 'D1');
|
// console.log(res);
|
||||||
ee.on('trigger', time => {
|
// console.log(inst.info);
|
||||||
if (time < 10) {
|
// });
|
||||||
return 0;
|
|
||||||
}
|
inst.onTrigger('D1', time => {
|
||||||
|
if (time > 10) {
|
||||||
if (start == 0) {
|
if (start == 0) {
|
||||||
start = time;
|
start = time;
|
||||||
} else {
|
} else {
|
||||||
stop = time;
|
stop = time;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const s = fs.createReadStream(dir + fileName);
|
const s = fs.createReadStream(dir + fileName);
|
||||||
s.on('data', chunk => {
|
|
||||||
if (lib.execute(cxt, ee.emit.bind(ee), chunk) === 0) {
|
s.on('data', inst.execute);
|
||||||
goodChunks++;
|
|
||||||
}
|
|
||||||
len += chunk.length;
|
|
||||||
chunks++;
|
|
||||||
});
|
|
||||||
s.on('end', () => {
|
s.on('end', () => {
|
||||||
// const info = lib.getInfo(cxt);
|
console.log(fileName, (stop - start), ((Date.now() - t0) / 1000 + 's'));
|
||||||
// console.log(info);
|
|
||||||
console.log(fileName, chunks, len, goodChunks, (stop - start),
|
|
||||||
((Date.now() - t0) / 1000 + 's')
|
|
||||||
);
|
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
}, () => {
|
}, () => {
|
||||||
|
36
index.js
36
index.js
@ -1,8 +1,38 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const EventEmitter = require('events').EventEmitter;
|
||||||
const pkg = require('./package.json');
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
let lib = require('bindings')('vcd.node');
|
let lib = require('bindings')('vcd.node');
|
||||||
lib.version = pkg.version;
|
|
||||||
|
|
||||||
module.exports = lib;
|
const version = pkg.version;
|
||||||
|
|
||||||
|
module.exports = () => {
|
||||||
|
const lifee = new EventEmitter();
|
||||||
|
const triee = new EventEmitter();
|
||||||
|
|
||||||
|
const lifemit = lifee.emit.bind(lifee);
|
||||||
|
const triemit = triee.emit.bind(triee);
|
||||||
|
|
||||||
|
const info = {path: []};
|
||||||
|
|
||||||
|
const cxt = lib.init(lifemit, triemit, info);
|
||||||
|
|
||||||
|
const execute = chunk => lib.execute(cxt, lifemit, triemit, info, chunk);
|
||||||
|
|
||||||
|
const on = (id, fn) => {
|
||||||
|
lifee.on(id, fn);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onTrigger = (id, fn) => {
|
||||||
|
lib.setTrigger(cxt, id);
|
||||||
|
triee.on(id, fn);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
version,
|
||||||
|
info,
|
||||||
|
execute,
|
||||||
|
on,
|
||||||
|
onTrigger
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -1,52 +1,45 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const expect = require('chai').expect;
|
const expect = require('chai').expect;
|
||||||
const lib = require('../index.js');
|
const vcd = require('../index.js');
|
||||||
|
|
||||||
describe('basic', () => {
|
describe('basic', () => {
|
||||||
it('type', done => {
|
|
||||||
expect(lib).to.be.an('object');
|
it('typeof vcd', done => {
|
||||||
|
expect(vcd).to.be.an('function');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
it('type', done => {
|
|
||||||
const cxt = lib.init();
|
it('typeof vcd instance', done => {
|
||||||
expect(cxt).to.be.an('object');
|
expect(vcd()).to.be.an('object');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fail: foo bar', done => {
|
it('fail: foo bar', done => {
|
||||||
const cxt = lib.init();
|
const inst = vcd();
|
||||||
expect(lib.execute(cxt, () => {}, Buffer.from(' foo bar ???'))).to.eq(1);
|
expect(inst.execute(Buffer.from(' foo bar ???'))).to.eq(1);
|
||||||
expect(lib.getInfo(cxt)).to.deep.eq({
|
expect(inst.info).to.deep.eq({
|
||||||
error: 1,
|
path: [],
|
||||||
reason: 'Expected declaration command',
|
status: 'declaration'
|
||||||
command: 0,
|
|
||||||
type: 0,
|
|
||||||
size: 0,
|
|
||||||
time: 0,
|
|
||||||
trigger: ''
|
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$comment', done => {
|
it('$comment', done => {
|
||||||
const cxt = lib.init();
|
const inst = vcd();
|
||||||
expect(lib.execute(cxt, () => {}, Buffer.from(
|
expect(inst.execute(Buffer.from(
|
||||||
' \n $comment some text $end $comment more text $end ???'
|
' \n $comment some text $end $comment more text $end ???'
|
||||||
))).to.eq(1);
|
))).to.eq(1);
|
||||||
expect(lib.getInfo(cxt)).to.deep.eq({
|
expect(inst.info).to.deep.eq({
|
||||||
error: 1,
|
path: [],
|
||||||
reason: 'Expected declaration command',
|
status: 'declaration'
|
||||||
command: 1,
|
|
||||||
type: 0,
|
|
||||||
size: 0,
|
|
||||||
time: 0,
|
|
||||||
trigger: ''
|
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('$version', done => {
|
it('$version', done => {
|
||||||
const cxt = lib.init();
|
const inst = vcd();
|
||||||
expect(lib.execute(cxt, () => {}, Buffer.from(
|
expect(inst.execute(Buffer.from(`
|
||||||
`
|
|
||||||
$version Generated by VerilatedVcd $end
|
$version Generated by VerilatedVcd $end
|
||||||
$date Wed Sep 18 22:59:07 2019
|
$date Wed Sep 18 22:59:07 2019
|
||||||
$end
|
$end
|
||||||
@ -61,8 +54,9 @@ $timescale 1ns $end
|
|||||||
|
|
||||||
$enddefinitions $end
|
$enddefinitions $end
|
||||||
`
|
`
|
||||||
))).to.eq(0); expect(lib.execute(cxt, () => {}, Buffer.from(
|
))).to.eq(0);
|
||||||
`
|
|
||||||
|
expect(inst.execute(Buffer.from(`
|
||||||
|
|
||||||
#1
|
#1
|
||||||
0"}G
|
0"}G
|
||||||
@ -79,17 +73,12 @@ b0000000011110000 {u
|
|||||||
b0000000000001111 {u
|
b0000000000001111 {u
|
||||||
`
|
`
|
||||||
))).to.eq(0);
|
))).to.eq(0);
|
||||||
// expect(lib.getInfo(cxt)).to.deep.eq({
|
|
||||||
// error: 0,
|
expect(inst.info).to.deep.eq({
|
||||||
// reason: 'NO REASON',
|
path: [],
|
||||||
// command: 19,
|
status: 'simulation'
|
||||||
// type: 17,
|
});
|
||||||
// size: 64,
|
|
||||||
// time: 303,
|
|
||||||
// start: 300,
|
|
||||||
// stop: 303,
|
|
||||||
// trigger: ''
|
|
||||||
// });
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
91
vcd.c
91
vcd.c
@ -90,39 +90,88 @@
|
|||||||
var = name; \
|
var = name; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// napi_value * var;
|
#define ASSERT_OBJECT(name, var) { \
|
||||||
|
napi_valuetype valuetype; \
|
||||||
|
if (napi_typeof(env, name, &valuetype) != napi_ok) { \
|
||||||
|
napi_throw(env, name); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
if (valuetype != napi_object) { \
|
||||||
|
napi_throw_type_error(env, 0, "Wrong arguments"); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
var = name; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
METHOD(init) {
|
METHOD(init) {
|
||||||
|
napi_value res;
|
||||||
|
|
||||||
struct vcd_parser_s *state = malloc(sizeof *state);
|
struct vcd_parser_s *state = malloc(sizeof *state);
|
||||||
|
|
||||||
const int32_t error = vcd_parser_init(state);
|
const int32_t error = vcd_parser_init(state);
|
||||||
|
if (error) {
|
||||||
|
ASSERT(res, napi_create_int32(env, error, &res))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_ARGC(3)
|
||||||
|
ASSERT_FUNCTION(args[0], state->lifee)
|
||||||
|
ASSERT_FUNCTION(args[1], state->triee)
|
||||||
|
ASSERT_OBJECT(args[2], state->hier)
|
||||||
|
|
||||||
static char triggerString [256];
|
static char triggerString [256];
|
||||||
|
|
||||||
state->trigger = triggerString;
|
state->trigger = triggerString;
|
||||||
state->reason = "NO REASON";
|
state->reason = "NO REASON";
|
||||||
|
state->napi_env = env;
|
||||||
|
|
||||||
|
napi_value status;
|
||||||
|
ASSERT(status, napi_create_string_latin1(env, "declaration", NAPI_AUTO_LENGTH, &status))
|
||||||
|
ASSERT(state->hier, napi_set_named_property(env, state->hier, "status", status))
|
||||||
|
|
||||||
|
// napi_value hierObj;
|
||||||
|
// ASSERT(hierObj, napi_create_object(env, &hierObj))
|
||||||
|
// state->hier = hierObj;
|
||||||
|
|
||||||
|
// ASSERT(state->hier, napi_create_object(env, &state->hier))
|
||||||
|
|
||||||
napi_value res;
|
|
||||||
if (error) {
|
|
||||||
ASSERT(res, napi_create_int32(env, error, &res))
|
|
||||||
} else {
|
|
||||||
ASSERT(res, napi_create_external(env, state, 0, 0, &res))
|
ASSERT(res, napi_create_external(env, state, 0, 0, &res))
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(done) {
|
||||||
|
ASSERT_ARGC(4)
|
||||||
|
struct vcd_parser_s *state;
|
||||||
|
// last use of all external objects
|
||||||
|
napi_value lifee, triee, hier;
|
||||||
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
|
ASSERT_FUNCTION(args[1], lifee)
|
||||||
|
ASSERT_FUNCTION(args[2], triee)
|
||||||
|
ASSERT_OBJECT(args[3], hier)
|
||||||
|
|
||||||
|
// FIXME destroy parser state
|
||||||
|
|
||||||
|
const int32_t error = 0;
|
||||||
|
napi_value res;
|
||||||
|
ASSERT(res, napi_create_int32(env, error, &res))
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(execute) {
|
METHOD(execute) {
|
||||||
ASSERT_ARGC(3)
|
ASSERT_ARGC(5)
|
||||||
struct vcd_parser_s *state;
|
struct vcd_parser_s *state;
|
||||||
ASSERT_EXTERNAL(args[0], state)
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
ASSERT_FUNCTION(args[1], state->emit)
|
ASSERT_FUNCTION(args[1], state->lifee)
|
||||||
ASSERT_BUFFER(args[2], p, plen)
|
ASSERT_FUNCTION(args[2], state->triee)
|
||||||
|
ASSERT_OBJECT(args[3], state->hier)
|
||||||
|
ASSERT_BUFFER(args[4], p, plen)
|
||||||
|
|
||||||
state->napi_env = env;
|
state->napi_env = env;
|
||||||
|
|
||||||
const int32_t error = vcd_parser_execute(state, p, p + plen);
|
const int32_t error = vcd_parser_execute(state, p, p + plen);
|
||||||
|
|
||||||
napi_value res;
|
napi_value res;
|
||||||
ASSERT(res, napi_create_int32(env, error, &res))
|
ASSERT(res, napi_create_int32(env, error, &res))
|
||||||
return res;
|
return res;
|
||||||
@ -134,27 +183,24 @@ METHOD(getInfo) {
|
|||||||
ASSERT_EXTERNAL(args[0], state)
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
|
|
||||||
napi_value infObj, error, reason, command, type, size, time, trigger;
|
napi_value infObj, error, reason, command, type, size, time, trigger;
|
||||||
|
|
||||||
ASSERT(infObj, napi_create_object(env, &infObj))
|
ASSERT(infObj, napi_create_object(env, &infObj))
|
||||||
|
|
||||||
ASSERT(error, napi_create_int32(env, state->error, &error))
|
ASSERT(error, napi_create_int32(env, state->error, &error))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "error", error))
|
|
||||||
|
|
||||||
ASSERT(reason, napi_create_string_latin1(env, state->reason, NAPI_AUTO_LENGTH, &reason))
|
ASSERT(reason, napi_create_string_latin1(env, state->reason, NAPI_AUTO_LENGTH, &reason))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "reason", reason))
|
|
||||||
|
|
||||||
ASSERT(command, napi_create_int32(env, state->command, &command))
|
ASSERT(command, napi_create_int32(env, state->command, &command))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "command", command))
|
|
||||||
|
|
||||||
ASSERT(type, napi_create_int32(env, state->type, &type))
|
ASSERT(type, napi_create_int32(env, state->type, &type))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "type", type))
|
|
||||||
|
|
||||||
ASSERT(size, napi_create_int32(env, state->size, &size))
|
ASSERT(size, napi_create_int32(env, state->size, &size))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "size", size))
|
|
||||||
|
|
||||||
ASSERT(time, napi_create_int32(env, state->time, &time))
|
ASSERT(time, napi_create_int32(env, state->time, &time))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "time", time))
|
|
||||||
|
|
||||||
ASSERT(trigger, napi_create_string_latin1(env, state->trigger, NAPI_AUTO_LENGTH, &trigger))
|
ASSERT(trigger, napi_create_string_latin1(env, state->trigger, NAPI_AUTO_LENGTH, &trigger))
|
||||||
|
|
||||||
|
// ASSERT(state->hier, napi_create_object(env, &state->hier))
|
||||||
|
ASSERT(infObj, napi_set_named_property(env, infObj, "hier", state->hier))
|
||||||
|
ASSERT(infObj, napi_set_named_property(env, infObj, "error", error))
|
||||||
|
ASSERT(infObj, napi_set_named_property(env, infObj, "reason", reason))
|
||||||
|
ASSERT(infObj, napi_set_named_property(env, infObj, "command", command))
|
||||||
|
ASSERT(infObj, napi_set_named_property(env, infObj, "type", type))
|
||||||
|
ASSERT(infObj, napi_set_named_property(env, infObj, "size", size))
|
||||||
|
ASSERT(infObj, napi_set_named_property(env, infObj, "time", time))
|
||||||
ASSERT(infObj, napi_set_named_property(env, infObj, "trigger", trigger))
|
ASSERT(infObj, napi_set_named_property(env, infObj, "trigger", trigger))
|
||||||
|
|
||||||
return infObj;
|
return infObj;
|
||||||
@ -173,6 +219,7 @@ METHOD(setTrigger) {
|
|||||||
|
|
||||||
napi_value Init(napi_env env, napi_value exports) {
|
napi_value Init(napi_env env, napi_value exports) {
|
||||||
DECLARE_NAPI_METHOD("init", init)
|
DECLARE_NAPI_METHOD("init", init)
|
||||||
|
DECLARE_NAPI_METHOD("done", done)
|
||||||
DECLARE_NAPI_METHOD("execute", execute)
|
DECLARE_NAPI_METHOD("execute", execute)
|
||||||
DECLARE_NAPI_METHOD("getInfo", getInfo)
|
DECLARE_NAPI_METHOD("getInfo", getInfo)
|
||||||
DECLARE_NAPI_METHOD("setTrigger", setTrigger)
|
DECLARE_NAPI_METHOD("setTrigger", setTrigger)
|
||||||
|
90
vcd_spans.c
90
vcd_spans.c
@ -3,6 +3,11 @@
|
|||||||
#include "vcd_parser.h"
|
#include "vcd_parser.h"
|
||||||
#include <node_api.h>
|
#include <node_api.h>
|
||||||
|
|
||||||
|
#define ASSERT(val, expr) \
|
||||||
|
if (expr != napi_ok) { \
|
||||||
|
napi_throw(env, val); \
|
||||||
|
}
|
||||||
|
|
||||||
int stringEq (
|
int stringEq (
|
||||||
const unsigned char* gold,
|
const unsigned char* gold,
|
||||||
const unsigned char* p,
|
const unsigned char* p,
|
||||||
@ -19,56 +24,65 @@ int stringEq (
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int commandSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
int commandSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
return 0;
|
napi_env env = state->napi_env;
|
||||||
};
|
|
||||||
|
|
||||||
int scopeIdentifierSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
if (state->command == 5) {
|
||||||
|
// printf(")");
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
int varSizeSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
if (state->command == 8) { // $enddefinitions
|
||||||
s->size = strtol((const char *)p, (char **)&endp, 10);
|
napi_value status;
|
||||||
|
ASSERT(status, napi_create_string_latin1(env, "simulation", NAPI_AUTO_LENGTH, &status))
|
||||||
|
ASSERT(state->hier, napi_set_named_property(env, state->hier, "status", status))
|
||||||
|
|
||||||
|
napi_value undefined, eventName, eventPayload, return_val;
|
||||||
|
ASSERT(undefined, napi_get_undefined(env, &undefined))
|
||||||
|
ASSERT(eventName, napi_create_string_latin1(env, "$enddefinitions", NAPI_AUTO_LENGTH, &eventName))
|
||||||
|
// ASSERT(eventPayload, napi_create_string_latin1(env, "payload", NAPI_AUTO_LENGTH, &eventPayload))
|
||||||
|
napi_value* argv[] = { &eventName }; // , &eventPayload };
|
||||||
|
ASSERT(state->lifee, napi_call_function(env, undefined, state->lifee, 1, *argv, &return_val))
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scopeIdentifierSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
|
// printf("(%d:%d", state->type, state->size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int varSizeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
|
state->size = strtol((const char *)p, (char **)&endp, 10);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int varIdSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
|
// printf(" %d", state->type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
|
napi_env env = state->napi_env;
|
||||||
if (stringEq((state->trigger), p, endp)) {
|
if (stringEq((state->trigger), p, endp)) {
|
||||||
napi_value undefined;
|
napi_value undefined, eventName, eventPayload, return_val;
|
||||||
if (napi_get_undefined(state->napi_env, &undefined) != napi_ok) {
|
ASSERT(undefined, napi_get_undefined(env, &undefined))
|
||||||
napi_throw(state->napi_env, undefined);
|
ASSERT(eventName, napi_create_string_latin1(env, state->trigger, NAPI_AUTO_LENGTH, &eventName))
|
||||||
return 0;
|
ASSERT(eventPayload, napi_create_int32(env, state->time, &eventPayload))
|
||||||
}
|
|
||||||
|
|
||||||
napi_value eventName;
|
|
||||||
if (napi_create_string_latin1(state->napi_env, "trigger", NAPI_AUTO_LENGTH, &eventName) != napi_ok) {
|
|
||||||
napi_throw(state->napi_env, eventName);
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
napi_value eventPayload;
|
|
||||||
if (napi_create_int32(state->napi_env, state->time, &eventPayload) != napi_ok) {
|
|
||||||
napi_throw(state->napi_env, eventPayload);
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
napi_value* argv[] = { &eventName, &eventPayload };
|
napi_value* argv[] = { &eventName, &eventPayload };
|
||||||
|
ASSERT(state->triee, napi_call_function(env, undefined, state->triee, 2, *argv, &return_val))
|
||||||
napi_value return_val;
|
|
||||||
if (napi_call_function(state->napi_env, undefined, state->emit, 2, *argv, &return_val) != napi_ok) {
|
|
||||||
napi_throw(state->napi_env, state->emit);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
int vectorSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
int vectorSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
// printf("{%.*s}", (int)(endp - p - 1), p);
|
// printf("{%.*s}", (int)(endp - p - 1), p);
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
int timeSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
int timeSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) {
|
||||||
s->time = strtol((const char *)p, (char **)&endp, 10);
|
state->time = strtol((const char *)p, (char **)&endp, 10);
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user