Error, missing operation after conditional break - break

I am trying to run this procedure, but am getting an "Error, missing operation", highlighting the conditional break:
is_prime := proc()
    local i, x_check;
    printf(`Enter an integer to check if it is a prime number...`);
    x_check:=parse(readline(terminal));
    if x_check<=2 then
        printf(cat(x_check,` is a prime number.`));
    else
        for i from 2 to x_check-1 do
              if (irem(x_check,i)=0) then
                 printf(cat(x_check,` is not a prime number.`));
                 break 2;
            end if;
          end do;
        printf(cat(x_check,` is a prime number.`));
     end if;
end proc:
If I don't include the integer, I am able to run the procedure, but it does not function like I would like it to. I am running Maple 2022, and can successfully run the example conditional break code in the Help. What is wrong with my use of break?
I am unfamiliar with conditional break, so beyond removing the integer, I do not know what else to try. I wanted to exit out of the outer if statement, and thought break would be able to do this so that my last printf statement is not displayed.

The break functionality is for do-loops, not if-then.
So your expectation of its breaking out of the your outer if-then is not reasonable.
The reason that you're getting an error message is that you attempted break 2 within only a single level (ie. unnested) do-loop. So it's invalid to instruct it there to break out of two levels of looping.
Since there's nothing else that you don't want to happen at the stage in question, you could get by with just return at that juncture.
It's not best practice to use name-quotes (single left-ticks) inside printf, for the English text. Those are just names, and in the worst scenario might even have been assigned some value. (Unlikely, but let's be careful.) Instead, the printf command offers its own neat syntax for formatting its message, using safe strings. Let's do that below.
And, for fun, I changed your readline to a readstat, to get a more meaningful title in the popup query.
is_prime := proc()
local i, x_check;
x_check:=readstat("Enter an integer to test its primality");
if not type(x_check,posint) then return
elif x_check<=2 then
printf("%a is a prime number.\n",x_check);
else
for i from 2 to x_check-1 do
if (irem(x_check,i)=0) then
printf("%a is not a prime number.\n",x_check);
return;
end if;
end do;
printf("%a is a prime number.\n",x_check);
end if;
end proc:
is_prime();
ps. Do you want to handle the input 1 differently?

Related

Rust lifetimes in async wrapper for sync code

I am trying to create a Stream using a camera with a blocking capture method. The blocking call is wrapped with blocking::unblock.
use futures::stream;
use rscam::{Camera, Config};
fn frame_stream() -> impl stream::Stream {
let mut camera = Camera::new("/dev/video0").unwrap();
camera.start(&Config {
interval: (1, 30),
resolution: (1280, 720),
format: b"H264",
..Default::default()
}).unwrap();
stream::unfold(camera, |c| async move {
let frame = blocking::unblock(|| c.capture().unwrap()).await;
Some((frame, c))
})
}
Compiling gives this error message:
error[E0373]: closure may outlive the current function, but it borrows `c`, which is owned by the current function
--> src/lib.rs:15:39
|
15 | let frame = blocking::unblock(|| c.capture().unwrap()).await;
| ^^ - `c` is borrowed here
| |
| may outlive borrowed value `c`
|
note: function requires argument type to outlive `'static`
--> src/lib.rs:15:21
|
15 | let frame = blocking::unblock(|| c.capture().unwrap()).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `c` (and any other referenced variables), use the `move` keyword
|
15 | let frame = blocking::unblock(move || c.capture().unwrap()).await;
| ++++
error[E0505]: cannot move out of `c` because it is borrowed
--> src/lib.rs:17:22
|
15 | let frame = blocking::unblock(|| c.capture().unwrap()).await;
| ------------------------------------------
| | | |
| | | borrow occurs due to use in closure
| | borrow of `c` occurs here
| argument requires that `c` is borrowed for `'static`
16 |
17 | Some((frame, c))
| ^ move out of `c` occurs here
How can I guarantee to the compiler that the reference to c taken in the closure will still be valid? I assume it will be, since execution of the closure is awaited before c is returned.
Solution
stream::unfold(camera, |c| async move {
Some(
blocking::unblock(|| {
(c.capture().unwrap(), c)
}).await
)
})
You could move the camera into the inner closure, then return it once the frame capture is complete:
stream::unfold(camera, |c| async move {
Some(blocking::unblock(|| move {
let frame = c.capture().unwrap()).await;
(frame,c)
})
})
.await does not guarantee liveness. This is the general problem of scoped async tasks. Futures can be canceled at any time. Consider:
let future = async {
let local = 123;
blocking::unblock(|| local).await;
};
// Poll `future`, but only once.
futures::block_on(async move { futures::poll!(future) });
We started a task using local data, then dropped the future. The task continues executing but the local data is gone. For this reason, there is currently no sound way to expose an async API allowing using local data similar to scoped threads. You have to use 'static data, for example by wrapping in Arc.
See also blocking issue #4.

Create BSTR from ASCIIZ PTR in PowerBasic sqlite3 Wrapper

I'm building a small wrapper for some sqlite3 functions.
sqlite3.dll has a function sqlite3_column_text16() that returns a UTF-16 string. This seems like the right function to call since PowerBasic and Windows (and OLE) use UTF-16 natively (called a BSTR), however, when I do this:
LOCAL pzValue AS ASCIIZ PTR
LOCAL ValLen AS LONG
LOCAL ColText AS STRING
pzValue = sqlite3_column_text16(ppStmt, 0) 'Returns column text ("Russ")
ValLen = sqlite3_column_bytes16(ppStmt, 0) 'Returns the byte length of column text (8)
ColText = &pzValue 'Assign a ASCIIZ PTR to a STRING - ISSUE HERE[/CODE]
ColText only contains the first letter of the UTF-16 string.
This makes sense (I think) because it's a UTF-16 string, so the first byte is valid ASCII, but the second byte is zero (null), so in the assignment ColText = &pzValue, ColText is assigned all the text up to the first null character. In this case, the string is "Russ", so the bytes in the UTF-16 are "R0u0s0s0" (each ASCII character is followed by a null (0).
So, how do I convert this UTF-16 string to a PowerBasic STRING (which is a BSTR)?
I checked some sqlite3 wrappers and found this code (SQLiteningServer.bas):
llColLength = sqlite3_column_bytes(rhSet, llDo)
if llColLength and llColLength <= 253 then
    ' It is not weird
    lsaColumns(llDo) = mkbyt$(llColLength) & peek$(sqlite3_column_blob(rhSet, llDo), llColLength)
elseif llColLength = 0 then
    ' Its zero so check type for NULL
    if sqlite3_column_type(rhSet, llDo) = 5 then
        lsaColumns(llDo) = mkbyt$(254)
    else
        lsaColumns(llDo) = mkbyt$(0)
    end if
else
    ' It is too long so add a Long
    lsaColumns(llDo) = mkbyt$(255) & mkl$(llColLength) & peek$(sqlite3_column_blob(rhSet, llDo), llColLength)
end if
So, in this code they are doing this:
lsaColumns(llDo) = mkbyt$(llColLength) & peek$(sqlite3_column_blob(rhSet, llDo), llColLength)
Which almost looks like they are constructing a BSTR in memory, but not exactly. To be a valid BSTR, the leading numeric value should be an INT16 indicating the byte length of the string, but in the code above, they are using a leading BYTE, so it's not a valid BSTR, right? I don't know.
How do I take a UTF-16 string returned by sqlite3_column_text16(ppStmt, 0) and convert it to a PowerBasic STRING (which is a standard OLE BSTR).
A BSTR is a pointer to a string of wide characters followed by a null character. The word preceding the text (at pointer -2) is the length of the string.
Look at SysAllocString(...) and SysAllocStringLen(...) for simple methods of creating a BSTR from your UTF-16 text

Eliminate left recursion in XText

This is part of the grammar of the NuSMV language:
BasicExpression:
Constant | '(' BasicExpression ')' | '!' BasicExpression | BasicExpression '&' BasicExpression;
Constant:
BooleanConstant
BooleanConstant:
'TRUE' | 'FALSE';
Unfortunately XText is throwing an exception that states there is left recursion in this grammar.
How can I fix it?
Thanks.
You could simply introduce a new rule (a new tier) like that:
BasicExpression:
firstContent=ExpressionContent ("&" secondContent=ExpressionContent)?
;
ExpressionContent:
Constant
| '(' BasicExpression ')'
| '!' BasicExpression
;
That way the rule is not left recursive anymore.
Greeting Krzmbrzl
Have a look at this article or the official documentation, it will explain in detail how to handle recursion in language, and taking into account operator precedence.

FreePascal: Free pointer to class

I'm writing a DLL to interface with Game Maker. (Game maker only deals in Doubles.)
Here's a function:
function CreateBitmap(W, H: Double): Double;
var
TBM: TBitmap;
begin
TBM := TBitmap.Create(Floor(W), Floor(H));
CreateBitmap := Double(Integer(#TBM));
end;
So when I get the Double back:
function DestroyBitmap(Handle: Double);
begin
<How do I free it?>
end;
How do I free this Double? I tried doing
function DestroyBitmap(Handle: Double);
var
Blittable: IBlittable;
begin
Blittable := Pointer(Floor(Handle))^
Blittable.Free;
end;
But since the pointer's type cannot be determined, the Blittable (IBlittable) cannot be set to "untyped".
How do I free this pointer without leaking memory?
Remove # - that gets the address of the local variable:
function CreateBitmap(W, H: Double): Double;
var
  TBM: TBitmap;
begin
  TBM := TBitmap.Create(Floor(W), Floor(H));
  CreateBitmap := Double(Integer(TBM));
end;
function DestroyBitmap(Handle: Double);
var
bmp: TBitmap;
begin
bmp := TBitmap(integer(Handle));
bmp.Free;
end;

Pypy: Why does a "simpler" nested list take longer to flatten?

I had the need to flatten some nested lists. After writing the flatten function, I naturally tried to see how many ways I could break it. I finally ran it through pypy and was delighted to discover that when the lists got really deep pypy was running significantly faster than cpython.
However, I'm seeing a strange situation where a test with a larger, more complicated list, with a larger variety of elements is actually executing faster than the "simpler" list.
Test 1, which has fewer elements, is consistently about a second slower to run (using time pypy ./script.py) than test 2.
def flatten(lol):
if not any([isinstance(i, list) for i in lol]):
return lol
flatter = [i for i in lol if not isinstance(i, list)]
for sublist in lol:
if isinstance(sublist, list):
flatter.extend(sublist)
return flatten(flatter)
def silly(l):
return [l, [l]]
nested_function = [["kaplutis", ["mucus", ["my brain", ["is","filled",["with",["pus",]]]]]], "santa gertrudis",[[[[["innermost",flatten(["in", "func"])]]]]]]
tuples = ["empty tuple retained-->", (), ("2-tuple not flattened",), ("I'm the only thing in this tuple")]
dicts = [{"hip": "hop", "ster": "toad"}]
lone_dict = {"lone": 1, "dict": 2}
silly_list = ["1"]
for i in range(20):
silly_list = silly(silly_list)
# test 1 - only the absurdly nested list
print(len(flatten(silly_list)))
# test 2 - absurdly nested list, with
lol = [nested_function, tuples, dicts, lone_dict, silly_list]
print(len(flatten(lol)))
The only thing I can figure is I'm running into some accidental optimization when the JIT is dealing with the simpler nested lists before "silly_list" in the second test.
this particular flatten function did hit various bad perf points in cpython and pypy
we figured it on irc some time ago and the fix was to create a completely different flatten function that was faster in cpython and much faster on pypy
i don't remember the url, it would be nice if OP would provide
the basic code was along the lines of
def flatten(items, akk=None)
if akk is None:
akk = []
for item in items:
if isinstance(item, list):
flatten(item, akk)
else:
akk.append(item)
an answer instead of a comment to include the code
It is hard to understand what your code does. Make sure it is correct. Optimize later. You could test the results against:
def flatten(lst, nonscalar_types=list):
    for x in lst:
        if isinstance(x, nonscalar_types):
            yield from flatten(x) # pep 380
        else:
            yield x # non-list type
Example
print(sum(1 for _ in flatten(lol)))

Resources