Continue out of FORALL loop in Chapel - chapel

When you write it all caps like that, you really see the FORTRAN heritage. Anyway, I can't get the forall continue syntax correct.
var ids = {1,2,3,5,7,11};
forall id in ids {
if id == 5 then writeln("High Five!!");
if id == 7 then continue;
writeln(id);
}
How does one properly "skip out of this loop" when using forall in Chapel?
== EDIT ==
Error is
error: break or continue is not in a loop

Beyond the misleading error message, I think you've simply run into an unimplemented feature in the current version of Chapel (1.16.0). I.e., I believe that this ought to work. Let's co-opt the issue you filed in the comments section above to continue the discussion.

Related

Bug in a fixed If - Else statement

this is my first post in this site.
As the title says, I encountered a bug in an If - else if - else block of codes.
What the problem is that, I am pretty confident that I have covered all 9 possible outcomes that there should be.
It is quite hard to explain more, so if you guys could take a look at my .cpp file and run it ( hopefully it runs because I used c++ on a mac), you may find an easier understanding of my problem.
source code cpp file
If you browse through my action();, in the else statement, I purposely displayed that you encountered a bug so just in case there were bugs, I'd be informed.
What I am trying to do is like this:
userinput | randomAImove | outcome
A 1 statement
A 2 statement
A 3 statement
D 1 statement
D 2 statement
D 3 statement
W 1 statement
W 2 statement
W 3 statement
else 1||2||3 statement
There are corresponding statements to each conditions met.
'A', 'W', 'D' are user input. I used a toupper command to force the compiler to just check on 'A' 'W' 'D'. However, the main problem I find is that, even if the toupper works(which I confirmed), the program displays the correct statement often but still somehow manages to bug even if the user(I tried it) input from A, W, D (not-case sensitive cuz of toupper).
Please just try it and after a few tries you may encounter it also. I wrote "you encountered a bug" if you ever do encounter it.
Please help me because I can't really see any other way to find the mistake. Maybe its in my plain sight but I can't seem to notice which one is it.
Thank you!
Change the AImove function to
void AImove()
{
turn = rand () % 3 + 1;
}
(add + 1), or you may get 0 in turn and it will lead you "encounter a bug".

Pascal: understanding if/then statements

I'm currently porting the VMS Pascal version of the classic Moria game, but I'm not sure if I'm understanding the limits of if/then statements (I've never programmed in Pascal before).
My understanding so far is that with no begin/end, then an if/then block only encloses one following statement. If that's the case, then in the following code;
if (i4 > 0) then
with inventory[i4] do
begin
objdes(out_val,i4,false);
msg_print('Your ' + out_val + ' glows faintly!');
if (enchant(toac)) then
begin
flags := uand(%X'7FFFFFFF',flags);
py_bonuses(blank_treasure,0);
end
else
msg_print('The enchantment fails...');
end;
ident := true;
the ident := true; would be outside of the if (tval > 0) then block, meaning that even if i4 is 0, ident would still be set to true.
If that is correct, then does it mean the following code from UMoria (a C port) is wrong?
i_ptr = &inventory[INVEN_WIELD];
if (i_ptr->tval != TV_NOTHING) {
objdes(tmp_str, i_ptr, FALSE);
(void) sprintf(out_val, "Your %s glows faintly!", tmp_str);
msg_print(out_val);
if (enchant(&i_ptr->tohit, 10))
{
i_ptr->flags &= ~TR_CURSED;
calc_bonuses();
}
else
msg_print("The enchantment fails.");
ident = TRUE;
}
...as the ident = TRUE; is inside the if block.
I've seen similar examples in several places -- I guess it's possible that these were changed for the C port -- but I'm hoping to get clarification before I change too much code.
Your assessment of the flow control is correct. However, the assignment of indent to true in the original Pascal code most likely was meant to be in the if/then statement due to the indentation.
This is why I always run an auto indentation on the source code in an IDE. It flushes out these bugs. (Python is an over reaction to this as I've seen indentation bugs in it and its not as amenable to automatic IDE help.)
I suspect the C port to be correct if someone proofread it and tested it.
Test driven development helps here as it helps define what is truly intended.

IF syntax error in simple VHDL code

I'm pretty new to vhdl and I can't seem to find the error in my code, I keep getting these errors.
alarm.vhdl (line 19, col 5): (E10) Syntax error at/before reserved symbol 'if'.
Error occurred within 'ARCHITECTURE' at line 16, column 28 in alarm.vhdl.
alarm.vhdl (line 31, col 9): (E56) Expected ;, but got IF
alarm.vhdl (line 31, col 9): (E10) Syntax error at/before reserved symbol 'if'.
alarm.vhdl (line 33, col 4): (E10) Syntax error at/before reserved symbol 'end'.
Is there something wrong with my if statement?
library IEEE;
use ieee.std_logic_1164.all;
entity alarm is
port( master_switch: in std_logic;
door_sensor: in std_logic;
wheel_sensor: in std_logic;
clock: in std_logic;
Z : out std_logic;
J : in std_logic_vector(1 downto 0);
K : in std_logic_vector(1 downto 0);
Q : inout std_logic_vector(1 downto 0);
Qcomp : inout std_logic_vector(1 downto 0) );
end alarm;
architecture behav of alarm is
begin
if clock='1' then
J(1) <= Qcomp(1) AND Q(0) AND master_switch AND door_sensor;
K(1) <= Q(0) OR Q(1);
J(0) <= Qcomp(0);
K(0) <= Qcomp(1) OR (Q(0) AND Q(1));
Q(1) <= ((NOT K(1)) AND Q(1)) OR (J(1) AND Qcomp(1));
Q(0) <= ((NOT K(0)) AND Q(0)) OR (J(0) AND Qcomp(0));
Z <= Q(1) AND Qcomp(0);
end if;
end;
end behav;
The if statement here must be in a process, with clock in its sensitivity list. (Also you want to use rising_edge(clock) rather than clock = '1' for correct synthesis)
on nebulous syntax error messages
alarm.vhdl (line 19, col 5): (E10) Syntax error at/before reserved symbol 'if'.
Error occurred within 'ARCHITECTURE' at line 16, column 28 in alarm.vhdl.
This is caused by a lack of a label preceding the reserved word if, presumed to be a generate statement scheme.
The issue being as Brian says that an if statement which is a sequential statement can only appear in a process, or a subprogram (a function or a procedure).
The apparent poor quality of the error message comes from how the error is detected in the parser.
The statements found inside an architecture statement part are concurrent statements:
architecture_statement_part ::=
{ concurrent_statement }
The curly brackets meaning zero or more concurrent statements are allowed (An architecture statement part can be empty).
concurrent_statement ::=
block_statement
| process_statement
| concurrent_procedure_call_statement
| concurrent_assertion_statement
| concurrent_signal_assignment_statement
| component_instantiation_statement
| generate_statement
A block statement begins with the reserved word block.
A process statement beginning with the reserved word process or postponed.
A concurrent procedure call statement beginning with the a procedure name or the reserved word postponed.
A concurrent assertion statement beginning with the reserved word assert.
A concurrent signal assignment statement beginning with the name of a signal or the keyword postponed.
A component instantiation statement beginning with the reserved word component, or the reserved word entity, or the reserved word configuration, or the name of an entity.
All the above concurrent statements may be optionally labeled, the label preceding either a reserved word or a name (an identifier, which can be a selected name).
The last choice for the generate statement requires a label and can have the reserved word if.
generate_statement ::=
generate_label :
generation_scheme generate
[ { block_declarative_item }
begin ]
{ concurrent_statement }
end generate [ generate_label ] ;
generation_scheme ::=
for generate_parameter_specification
| if condition
label ::= identifier
We see that after a mandatory label we'd expect to see the generation scheme, either indicated by the the reserved word if or the reserved word for.
The parser tested for these in order. You could note that concurrent_statement is not a terminal. One of the various concurrent statements would be a terminal production. Without the ability to hang an error message on a non-terminal everything will get swept up in the last concurrent statement choice (generate statement).
Rather than tell you there's something wrong with the generate statement:
ghdl -a alarm.vhdl
alarm.vhdl:19:1: a generate statement must have a label
alarm.vhdl:19:14: 'generate' is expected instead of 'then'
The parser you used told there's simply something wrong around the reserved word if. Although there is only one concurrent statement that can 'start' with if, the lack of a mandatory label aside.
A VHDL parser can operate with a look ahead of one, assuming semantic predicates are used (e.g. entity_name).
It's sometime possible to use a larger look ahead to avoid backtracking (which makes no sense in the last concurrent statement choice). There was an expression followed by the reserved word then, which disqualifies the current concurrent statement as a generate statement.
It's possible to produce a better error message:
nvc -a alarm.vhdl
** Error: syntax error, unexpected if, expecting process
File alarm.vhdl, Line 19
if clock='1' then
^^
This determining that if is inappropriate without being preceded by a label, and in the case of nvc noting that an if statement is a sequential statement, allowed in, in this case a process statement.
(Notice Brian's answer said "The if statement here must be in a process,..").
Note that neither ghdl nor nvc preceded beyond this error. ghdl treats the current portion of the design description as a generate statement (no non-terminal error messages), while nvc is capable of non-terminal error messages (not using a bison construct in this case). Your tool vendor's parser throws up it's hands a bit sooner but attempts a poor non-terminal error message.
However, there's no excuse or need for preceding further:
alarm.vhdl (line 31, col 9): (E56) Expected ;, but got IF
alarm.vhdl (line 31, col 9): (E10) Syntax error at/before reserved symbol 'if'.
alarm.vhdl (line 33, col 4): (E10) Syntax error at/before reserved symbol 'end'.
Why is an unknown concurrent statement choice being attempted when any error in parsing is sufficient to invalidate the output? There's an attempt to give more context, however referencing line and columns as well as reserved words is likely not the way to do it.
You could also note that nvc's error message can have shortcomings. Label the if statement and you get:
nvc -a alarm.vhdl
** Error: syntax error, unexpected then
File alarm.vhdl, Line 20
if clock='1' then
^^^^
The shortcoming here is that it doesn't tell you it's parsing a generate statement (nor does you're tool vendor's parser).
While ghdl gets a bit more specific:
ghdl -a alarm.vhdl
alarm.vhdl:20:14: 'generate' is expected instead of 'then'
ghdl: compilation error
And one of the things all three of these parsers has in common is that they all required VHDL language expertise to interpret.
In these cases a tool vendor could provide an expanded narrative optionally to explain how the message was produced.
For instance Modelsim has a verror facility which produces a narrative description when provided with an error number.
In your case you appear to be synthesizing the VHDL design description directly. In general a synthesis tool assumes some familiarity with VHDL, which might indicate you'd be better off simulating a design first or failing that based on complexity using a different analyzer to root out syntax errors.
Your error messages appear to come from Cypress's WARP, the Reference Manual (1996, PDF,1.4 MB) tells us:
E10 :Syntax error at/before reserved symbol ā€˜%sā€™.
You used a reserved word in an illegal fashion, e.g., as a signal or variable name.
And you can see the message is a bit less than helpful.
WARP is considered obsolete intended to support a discontinued CPLD line and discontinued itself in 2012, otherwise lacking in support. It reinforces the notion of analyzing your VHDL designs with another tool.

OCaml lex: doesn't work at all, whatsoever

I am at the end of my rope here. I cannot get anything to work in ocamllex, and it is driving me nuts. This is my .mll file:
{
open Parser
}
rule next = parse
| (['a'-'z'] ['a'-'z']*) as id { Identifier id }
| '=' { EqualsSign }
| ';' { Semicolon }
| '\n' | ' ' { next lexbuf }
| eof { EOF }
Here are the contents of the file I pass in as input:
a=b;
Yet, when I compile and run the thing, I get an error on the very first character, saying it's not valid. I honestly have no idea what's going on, and Google has not helped me at all. How can this even be possible? As you can see, I'm really stumped here.
EDIT:
I was working for so long that I gave up on the parser. Now this is the relevant code in my main file:
let parse_file filename =
let l = Lexing.from_channel (open_in filename) in
try
Lexer.next l; ()
with
| Failure msg ->
printf "line: %d, col: %d\n" l.lex_curr_p.pos_lnum l.lex_curr_p.pos_cnum
Prints out "line: 1, col: 1".
Without the corresponding ocamlyacc parser, nobody will be able to find the issue with your code since your lexer works perfectly fine!
I have taken the liberty of writing the following tiny parser (parser.mly) that constructs a list of identifier pairs, e.g. input "a=b;" should give the singleton list [("a", "b")].
%{%}
%token <string> Identifier
%token EqualsSign
%token Semicolon
%token EOF
%start start
%type <(string * string) list> start
%%
start:
| EOF {[]}
| Identifier EqualsSign Identifier Semicolon start {($1, $3) :: $5}
;
%%
To test whether the parser does what I promised, we create another file (main.ml) that parses the string "a=b;" and prints the result.
let print_list = List.iter (fun (a, b) -> Printf.printf "%s = %s;\n" a b)
let () = print_list (Parser.start Lexer.next (Lexing.from_string "a=b;"))
The code should compile (e.g. ocamlbuild main.byte) without any complaints and the program should output "a=b;" as promised.
In response to the latest edit:
In general, I don't believe that catching standard library exceptions that are meant to indicate failure or misuse (like Invalid_argument or Failure) is a good idea. The reason is that they are used ubiquitously throughout the library such that you usually cannot tell which function raised the exception and why it did so.
Furthermore, you are throwing away the only useful information: the error message! The error message should tell you what the source of the problem is (my best guess is an IO-related issue). Thus, you should either print the error message or let the exception propagate to the toplevel. Personally, I prefer the latter option.
However, you probably still want to deal with syntactically ill-formed inputs in a graceful manner. For this, you can define a new exception in the lexer and add a default case that catches invalid tokens.
{
exception Unexpected_token
}
...
| _ {raise Unexpected_token}
Now, you can catch the newly defined exception in your main file and, unlike before, the exception is specific to syntactically invalid inputs. Consequently, you know both the source and the cause of the exception giving you the chance to do something far more meaningful than before.
A fairly random OCaml development hint: If you compile the program with debug information enabled, setting the environment variable OCAMLRUNPARAM to "b" (e.g. export OCAMLRUNPARAM=b) enables stack traces for uncaught exceptions!
btw. ocamllex also can do the + operator for 'one or more' in regular expressions, so this
['a'-'z']+
is equivalent to your
['a'-'z']['a'-'z']*
I was just struggling with the same thing (which is how I found this question), only to finally realize that I had mistakenly specified the path to input file as Sys.argv.(0) instead of Sys.argv.(1)! LOLs
I really hope it helps! :)
It looks like you have a space in the regular expression for identifiers. This could keep the lexer from recognizing a=b, although it should still recognize a = b ;

Set Visual Studio (conditional) breakpoint on local variable value

I'm trying to debug a method which among other things, adds items to a list which is local to the method.
However, every so often the list size gets set to zero "midstream". I would like to set the debugger to break when the list size becomes zero, but I don't know how to, and would appreciate any pointers on how to do this.
Thanks.
Why not use conditional breakpoints?
http://blogs.msdn.com/saraford/archive/2008/06/17/did-you-know-you-can-set-conditional-breakpoints-239.aspx
in C#
if(theList.Count == 0){
//do something meaningless here .e.g.
int i = 1; // << set your breakpoint here
}
in VB.NET
If theList.Count = 0 Then
'do something meaningless here .e.g.
Dim i = 1; ' << set your breakpoint here
End If
For completeness sake, here's the C++ version:
if(theList->Count == 0){
//do something meaningless here .e.g.
int i = 1; // << set your breakpoint here
}
I can give a partial answer for Visual Studio 2005. If you open the "Breakpoints" window (Alt + F9) you get a list of breakpoints. Right-click on the breakpoint you want, and choose "Condition." Then put in the condition you want.
You have already got both major options suggested:
1. Conditional breakpoints
2. Code to check for the wrong value, and with a breakpoint if so happens
The first option is the easiest and best, but on large loops it is unfortunately really slow! If you loop 100's of thousands iterations the only real option is #2. In option #1 the cpu break into the debugger on each iteration, then it evaluates the condition and if the condition for breaking is false it just continiues execution of the program. This is slow when it happens thousands of times, it is actually slow if you loop just 1000 times (depending on hardware of course)
As I suspect you really want an "global" breakpoint condition that should break the program if a certain condition is met (array size == 0), unfortunately that does not exist to my knowledge. I have made a debugging function that checks the condition, and if it is true it does something meaningless that I have a breakpoint set to (i.e. option 2), then I call that function frequently where I suspect the original fails. When the system breaks you can use the call stack to identify the faulty location.