I am writing a mechanism to generate a unique ID derived from sha256. I use:
require 'sha2'
function getUint64ID( callId )
local minimumValue = 100000000000000000
local maximumValue = 999999999999999999
outputHash = sha2.sha256hex(callId)
print(outputHash .. "\n")
local c1 = ""
for a, b in outputHash:gmatch"(%x)(%x)" do
hexTuple = tostring(a) .. tostring(b)
intVal = tonumber(hexTuple, 16)
c1 = c1 .. string.char(intVal)
end
uint64ID = ( minimumValue + ( tonumber(c1) % ( maximumValue - minimumValue + 1 ) ) )
print('uint64ID:')
print(string.format("%18.0f",uint64ID))
end
getUint64ID("test")
I get the following error in the above code:
stdin:17: attempt to perform arithmetic on a nil value
stack traceback:
stdin:17: in function 'getUint64ID'
stdin:1: in main chunk
[C]: ?
How to convert 32 bytes char buffer (c1) into a uint64 number in lua?
I would want to ask, how do you break up a 32-bit hex (for example: CEED6644) into 4 bytes (var1 = CE, var2 = ED, var3 = 66, var4 = 44). In QB64 or QBasic. I would use this to store several data bytes into one array address.
Something like this:
DIM Array(&HFFFF&) AS _UNSIGNED LONG
Array(&HAA00&) = &HCEED6644&
addr = &HAA00&
SUB PrintChar
SHARED addr
IF var1 = &HAA& THEN PRINT "A"
IF var1 = &HBB& THEN PRINT "B"
IF var1 = &HCC& THEN PRINT "C"
IF var1 = &HDD& THEN PRINT "D"
IF var1 = &HEE& THEN PRINT "E"
IF var1 = &HFF& THEN PRINT "F"
IF var1 = &H00& THEN PRINT "G"
IF var1 = &H11& THEN PRINT "H"
And so on...
You could use integer division (\) and bitwise AND (AND) to accomplish this.
DIM x(0 TO 3) AS _UNSIGNED _BYTE
a& = &HCEED6644&
x(0) = (a& AND &HFF000000&) \ 2^24
x(1) = (a& AND &H00FF0000&) \ 2^16
x(2) = (a& AND &H0000FF00&) \ 2^8
x(3) = a& AND &HFF&
PRINT HEX$(x(0)); HEX$(x(1)); HEX$(x(2)); HEX$(x(3))
Note that you could alternatively use a generic RShift~& function instead of raw integer division since what you're really doing is shifting bits:
x(0) = RShift~&(a& AND &HFF000000&, 18)
...
FUNCTION RShift~& (value AS _UNSIGNED LONG, shiftCount AS _UNSIGNED BYTE)
' Raise illegal function call if the shift count is greater than the width of the type.
' If shiftCount is not _UNSIGNED, then you must also check that it isn't less than 0.
IF shiftCount > 32 THEN ERROR 5
RShift~& = value / 2^shiftCount
END FUNCTION
Building upon that, you might create another function:
FUNCTION ByteAt~%% (value AS _UNSIGNED LONG, position AS _UNSIGNED BYTE)
'position must be in the range [0, 3].
IF (position AND 3) <> position THEN ERROR 5
ByteAt~%% = RShift~&(value AND LShift~&(&HFF&, 8*position), 8*position)
END FUNCTION
Note that an LShift~& function was used that shifts bits to the left (multiplication by a power of 2). A potentially better alternative would be to perform the right-shift first and just mask the lower 8 bits, eliminating the need for LShift~&:
FUNCTION ByteAt~%% (value AS _UNSIGNED LONG, position AS _UNSIGNED BYTE)
'position must be in the range [0, 3].
IF (position AND 3) <> position THEN ERROR 5
ByteAt~%% = RShift~&(value, 8*position) AND 255
END FUNCTION
Incidentally, another QB-like implementation known as FreeBASIC has an actual SHR operator, used like MOD or AND, to perform a shift operation directly instead of using division, which is potentially faster.
You could also use QB64's DECLARE LIBRARY facility to create functions in C++ that will perform the shift operations:
/*
* Place in a separate "shift.h" file or something.
*/
unsigned int LShift (unsigned int n, unsigned char count)
{
return n << count;
}
unsigned int RShift (unsigned int n, unsigned char count)
{
return n >> count;
}
Here's the full corresponding QB64 code:
DECLARE LIBRARY "shift"
FUNCTION LShift~& (value AS _UNSIGNED LONG, shiftCount AS _UNSIGNED _BYTE)
FUNCTION RShift~& (value AS _UNSIGNED LONG, shiftCount AS _UNSIGNED _BYTE)
END DECLARE
x(0) = ByteAt~%%(a&, 0)
x(1) = ByteAt~%%(a&, 1)
x(2) = ByteAt~%%(a&, 2)
x(3) = ByteAt~%%(a&, 3)
END
FUNCTION ByteAt~%% (value AS _UNSIGNED LONG, position AS _UNSIGNED BYTE)
'position must be in the range [0, 3].
IF (position AND 3) <> position THEN ERROR 5
ByteAt~%% = RShift~&(value, 8*position) AND 255
END FUNCTION
If QB64 had a documented API, it might be possible to raise a QB64 error from the C++ code when the shift count is too high, rather than relying on the behavior of C++ to essentially ignore shift counts that are too high. Unfortunately, this isn't the case, and it might actually cause more problems than it's worth.
This snip gets the byte pairs of a hexidecimal value:
DIM Value AS _UNSIGNED LONG
Value = &HCEED6644&
S$ = RIGHT$("00000000" + HEX$(Value), 8)
PRINT "Byte#1: "; MID$(S$, 1, 2)
PRINT "Byte#2: "; MID$(S$, 3, 2)
PRINT "Byte#3: "; MID$(S$, 5, 2)
PRINT "Byte#4: "; MID$(S$, 7, 2)
I am struggling to get my head around LPEG. I have managed to produce one grammar which does what I want, but I have been beating my head against this one and not getting far. The idea is to parse a document which is a simplified form of TeX. I want to split a document into:
Environments, which are \begin{cmd} and \end{cmd} pairs.
Commands which can either take an argument like so: \foo{bar} or can be bare: \foo.
Both environments and commands can have parameters like so: \command[color=green,background=blue]{content}.
Other stuff.
I also would like to keep track of line number information for error handling purposes. Here's what I have so far:
lpeg = require("lpeg")
lpeg.locale(lpeg)
-- Assume a lot of "X = lpeg.X" here.
-- Line number handling from http://lua-users.org/lists/lua-l/2011-05/msg00607.html
-- with additional print statements to check they are working.
local newline = P"\r"^-1 * "\n" / function (a) print("New"); end
local incrementline = Cg( Cb"linenum" )/ function ( a ) print("NL"); return a + 1 end , "linenum"
local setup = Cg ( Cc ( 1) , "linenum" )
nl = newline * incrementline
space = nl + lpeg.space
-- Taken from "Name-value lists" in http://www.inf.puc-rio.br/~roberto/lpeg/
local identifier = (R("AZ") + R("az") + P("_") + R("09"))^1
local sep = lpeg.S(",;") * space^0
local value = (1-lpeg.S(",;]"))^1
local pair = lpeg.Cg(C(identifier) * space ^0 * "=" * space ^0 * C(value)) * sep^-1
local list = lpeg.Cf(lpeg.Ct("") * pair^0, rawset)
local parameters = (P("[") * list * P("]")) ^-1
-- And the rest is mine
anything = C( (space^1 + (1-lpeg.S("\\{}")) )^1) * Cb("linenum") / function (a,b) return { text = a, line = b } end
begin_environment = P("\\begin") * Ct(parameters) * P("{") * Cg(identifier, "environment") * Cb("environment") * P("}") / function (a,b) return { params = a[1], environment = b } end
end_environment = P("\\end{") * Cg(identifier) * P("}")
texlike = lpeg.P{
"document";
document = setup * V("stuff") * -1,
stuff = Cg(V"environment" + anything + V"bracketed_stuff" + V"command_with" + V"command_without")^0,
bracketed_stuff = P"{" * V"stuff" * P"}" / function (a) return a end,
command_with =((P("\\") * Cg(identifier) * Ct(parameters) * Ct(V"bracketed_stuff"))-P("\\end{")) / function (i,p,n) return { command = i, parameters = p, nodes = n } end,
command_without = (( P("\\") * Cg(identifier) * Ct(parameters) )-P("\\end{")) / function (i,p) return { command = i, parameters = p } end,
environment = Cg(begin_environment * Ct(V("stuff")) * end_environment) / function (b,stuff, e) return { b = b, stuff = stuff, e = e} end
}
It almost works!
> texlike:match("\\foo[one=two]thing\\bar")
{
command = "foo",
parameters = {
{
one = "two",
},
},
}
{
line = 1,
text = "thing",
}
{
command = "bar",
parameters = {
},
}
But! First, I can't get the line number handling part to work at all. The function within incrementline is never fired.
I also can't quite work out how nested capture information is passed to handling functions (which is why I have scattered Cg, C and Ct semirandomly over the grammar). This means that only one item is returned from within a command_with:
> texlike:match("\\foo{text \\command moretext}")
{
command = "foo",
nodes = {
{
line = 1,
text = "text ",
},
},
parameters = {
},
}
I would also love to be able to check that the environment start and ends match up but when I tried to do so, my back references from "begin" were not in scope by the time I got to "end". I don't know where to go from here.
Late answer but hopefully it'll offer some insight if you're still looking for a solution or wondering what the problem was.
There are a couple of issues with your grammar, some of which can be tricky to spot.
Your line increment here looks incorrect:
local incrementline = Cg( Cb"linenum" ) /
function ( a ) print("NL"); return a + 1 end,
"linenum"
It looks like you meant to create a named capture group and not an anonymous group. The backcapture linenum is essentially being used like a variable. The problem is because this is inside an anonymous capture, linenum will not update properly -- function(a) will always receive 1 when called. You need to move the closing ) to the end so "linenum" is included:
local incrementline = Cg( Cb"linenum" /
function ( a ) print("NL"); return a + 1 end,
"linenum")
Relevant LPeg documentation for Cg capture.
The second problem is with your anything non-terminal rule:
anything = C( (space^1 + (1-lpeg.S("\\{}")) )^1) * Cb("linenum") ...
There are several things to be careful here. First, a named Cg capture (from incrementline rule once it's fixed) doesn't produce anything unless it's in a table or you backref it. The second major thing is that it has an adhoc scope like a variable. More precisely, its scope ends once you close it in an outer capture -- like what you're doing here:
C( (space^1 + (...) )^1)
Which means by the time you reference its backcapture with * Cb("linenum"), that's already too late -- the linenum you really want already closed its scope.
I always found LPeg's re syntax a bit easier to grok so I've rewritten the grammar with that instead:
local grammar_cb =
{
fold = pairfold,
resetlinenum = resetlinenum,
incrementlinenum = incrementlinenum, getlinenum = getlinenum,
error = error
}
local texlike_grammar = re.compile(
[[
document <- '' -> resetlinenum {| docpiece* |} !.
docpiece <- {| envcmd |} / {| cmd |} / multiline
beginslash <- cmdslash 'begin'
endslash <- cmdslash 'end'
envcmd <- beginslash paramblock? {:beginenv: envblock :} (!endslash docpiece)*
endslash openbrace {:endenv: =beginenv :} closebrace / &beginslash {} -> error .
envblock <- openbrace key closebrace
cmd <- cmdslash {:command: identifier :} (paramblock? cmdblock)?
cmdblock <- openbrace {:nodes: {| docpiece* |} :} closebrace
paramblock <- opensq ( {:parameters: {| parampairs |} -> fold :} / whitesp) closesq
parampairs <- parampair (sep parampair)*
parampair <- key assign value
key <- whitesp { identifier }
value <- whitesp { [^],;%s]+ }
multiline <- (nl? text)+
text <- {| {:text: (!cmd !closebrace !%nl [_%w%p%s])+ :} {:line: '' -> getlinenum :} |}
identifier <- [_%w]+
cmdslash <- whitesp '\'
assign <- whitesp '='
sep <- whitesp ','
openbrace <- whitesp '{'
closebrace <- whitesp '}'
opensq <- whitesp '['
closesq <- whitesp ']'
nl <- {%nl+} -> incrementlinenum
whitesp <- (nl / %s)*
]], grammar_cb)
The callback functions are straight-forwardly defined as:
local function pairfold(...)
local t, kv = {}, ...
if #kv % 2 == 1 then return ... end
for i = #kv, 2, -2 do
t[ kv[i - 1] ] = kv[i]
end
return t
end
local incrementlinenum, getlinenum, resetlinenum do
local line = 1
function incrementlinenum(nl)
assert(not nl:match "%S")
line = line + #nl
end
function getlinenum() return line end
function resetlinenum() line = 1 end
end
Testing the grammar with a non-trivial tex-like str with multiple lines:
local test1 = [[\foo{text \bar[color = red, background = black]{
moretext \baz{
even
more text} }
this time skipping multiple
lines even, such wow!}]]
Produces the follow AST in lua-table format:
{
command = "foo",
nodes = {
{
text = "text",
line = 1
},
{
parameters = {
color = "red",
background = "black"
},
command = "bar",
nodes = {
{
text = " moretext",
line = 2
},
{
command = "baz",
nodes = {
{
text = "even ",
line = 3
},
{
text = "more text",
line = 4
}
}
}
}
},
{
text = "this time skipping multiple",
line = 7
},
{
text = "lines even, such wow!",
line = 9
}
}
}
And a second test for begin/end environments:
local test2 = [[\begin[p1
=apple,
p2=blue]{scope} scope foobar
\end{scope} global foobar]]
Which seems to give approximately what you're looking for:
{
{
{
text = " scope foobar",
line = 3
},
parameters = {
p1 = "apple",
p2 = "blue"
},
beginenv = "scope",
endenv = "scope"
},
{
text = " global foobar",
line = 4
}
}
It appears that F# automatically inlines some functions, even though they are not marked with "inline".
let a x= x + 3
let b x= x * x
let funB x y =
if x > y then 3
else 1
let funC x =
let s = a x
let c = funB s (b x)
c + 1
By inspecting IL, I see the compiler has aggressively inlined funB & a,b
funC:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.3
IL_0003: add
IL_0004: stloc.0 // s
IL_0005: ldarg.0
IL_0006: ldarg.0
IL_0007: mul
IL_0008: stloc.1
IL_0009: ldloc.0 // s
IL_000A: ldloc.1
IL_000B: ble.s IL_0011
IL_000D: ldc.i4.3
IL_000E: nop
IL_000F: br.s IL_0013
IL_0011: ldc.i4.1
IL_0012: nop
IL_0013: ldc.i4.1
IL_0014: add
IL_0015: ret
The behaviour looks strange to me. I had thought that the compiler should only inline if there is inline keyword. Are there any reference which mentioned it?
The inline keyword is a way of forcing the compiler to inline a function and as a result allows a function to take a type as a parameter and increases performance. There is no reason for the compiler to not inline functions as it sees fit for a release build.
to_expr function leads to error. Could you advise what is wrong below?
context z3_cont;
expr x = z3_cont.int_const("x");
expr y = z3_cont.int_const("y");
expr ge = ((y==3) && (x==2));
ge = swap_tree( ge );
where swap_tree is a function that shall swap all operands of binary operations. It defined as follows.
expr swap_tree( expr e ) {
Z3_ast ee[2];
if ( e.is_app() && e.num_args() == 2) {
for ( int i = 0; i < 2; ++i ) {
ee[ 1 - i ] = swap_tree( e.arg(i) );
}
for ( int i = 0; i < 2; ++i ) {
cout <<" ee[" << i << "] : " << to_expr( z3_cont, ee[ i ] ) << endl;
}
return to_expr( z3_cont, Z3_update_term( z3_cont, e, 2, ee ) );
}
else
return e;
}
The problem is "referencing counting". A Z3 object can be garbage collected by the system if its reference counter is 0. The Z3 C++ API provides "smart pointers" (expr, sort, ...) for automatically managing the reference counters for us. Your code uses Z3_ast ee[2]. In the for-loop, you store the result of swap_tree(e.arg(0)) into ee[0]. Since the reference counter is not incremented, this Z3 object may be deleted when executing the second iteration of the loop.
Here is a possible fix:
expr swap_tree( expr e ) {
if ( e.is_app() && e.num_args() == 2) {
// using smart-pointers to store the intermediate results.
expr ee0(z3_cont), ee1(z3_cont);
ee0 = swap_tree( e.arg(0) );
ee1 = swap_tree( e.arg(1) );
Z3_ast ee[2] = { ee1, ee0 };
return to_expr( z3_cont, Z3_update_term( z3_cont, e, 2, ee ) );
}
else {
return e;
}
}