VHDL Array element in if-statement - arrays

This is my first work with VHDL so it's surely something basic but just don't know what to do.
I have this code:
--this is in the architecture segment
type my_code is array(0 to 15) of integer;
signal code: my_code;
....
--here I use the array
code(count) <=0; --I save a value into the array on position defined by the count variable
if (code(0) = '0') then --fail line (want to do something if the first element is 0)
--do something
end if;
The compiler stops me because "can not have such operands in this context". The problem is on line with the if statement. What is wrong with that?
I am basically working on a digital lock like you write a code and it will open or remain closed if the code is wrong so I just want to check the array of pressed keys if the code in there is right.
Sorry for bothering but I just don't get it. Thanks and have a nice day ^^

You have an array of integers, so code(0) must be an integer. You cannot compare an integer to character literal '0'.
Either check for code(0) = 0 or redefine your array as type my_code is array(0 to 15) of bit; You can use bit or std_logic, or any other type that has '0' as valid element.

code is an array of integers. You are trying to compare it to a character literal '0', which has no interpretation as an enumeration literal in the context of integers. Try 0 instead.
Also the parentheses surrounding the expression (code(0) = '0') are redundant.
There is no operator defined to compare an integer to a type represented by a character literal in the code context (which you haven't display in your example, not having any context clauses visible nor other declarations).
The "=" equality operator to use is selected by comparing the input operands and result type. There is no operator visible by selection providing a left argument of integer and a right argument of some (not known from your code fragment) type represented by the character literal '0' as an enumeration literal.
Operators that can be selected among several possibilities based on operand type are said to be overloaded.
After a bit of Googling and finding the answer to the general question raised by this Xilinx error message to always dwell on the immediate case I found a few places you can look to understand the issue.
Reference texts:
There are two sub sections in IEEE Standard VHDL Language Reference Manual (the LRM, e.g. IEEE Std 1076-2008, -1993), entitled Subprogram overloading (operators on non predefined typed are functions) in the section Subprograms and packages, and The context of overload resolution in the section Scope and visibility.
VHDL: HARDWARE DESCRIPTION AND DESIGN, Lipsett, Schaefer and Ussery, 1989, Kluwer Academic Publishers.
Also Peter Ashenden and Jim Lewis's 3rd Edition of The Designer's Guide to VHDL, Morgan Kaufman, 2008.
The solution can be either expanding or adding a context clause for missing references to overloaded operators or fixing (as in your case) a syntax error. Which of the two can be case specific.

Related

Need to understand syntax in C program

I have been tasked with studying and modifying a C program. Generally, I write code in pl/sql, but not C. I have been able to decipher most of the code, but the program flow is still eluding me. After looking up several C references guides, I am not understanding how the C code works. I'm hoping someone here can answer a few syntax questions and tell me what each statement is trying to do.
Here is one sample, with my guesses below.
input(ask_fterm,TM_NLS_Get("0004","FROM TERM: "),6,ALPHA);
if ( !*ask_fterm ) goto opt_fterm;
tmstrcpy(fterm,ask_fterm);
goto nextparmb;
opt_fterm:
tmstrcpy(parm_no,_TMC("02"));
sel_optional_ind(FIRST_ROW);
if ( compare(rpt_optional_ind,_TMC("O"),EQS) ) goto nextparmb;
goto missing_parms;
First, I don't understand !*. What does the exclamation asterisk combination?
Second I assume that if must be ended with endif, unless it is on a single line?
Third tmstrcopy() apparently copies the value of the 2nd parameter into the 1st parameter?
I also have several parameters which I don't understand. I'm hoping someone gives me a hint.
tmstrcpy(valid_ind,_TMC("N"));
input(ask_toterm,TM_NLS_Get("0005","TO TERM: "),6,ALPHA);
I don't know where to find _TMC and TM_NLS_Get.
First, I don't understand !*. What does the exclamation asterisk combination?
That's two separate operators. ! is logical negation. Unary * is for dereferencing a pointer. Put together, they each have their separate effect, so !*ask_fterm means determine the value of the object to which pointer ask_fterm points (this is *); if that value is 0 then the result is 1, else the result is 0 (this is !). If ask_fterm is a pointer to the first character of a string, then that's a check for whether the string is empty (zero-length), because C strings are terminated by a character with value 0.
Second I assume that if must be ended with endif, unless it is on a single line?
There is no endif in C. An if construct controls exactly one statement, but that can be and often is a compound one (which you can recognize by the { and } delimiters enclosing it). There may also be an else clause, also controlling exactly one statement, which can be a compound one.
Third tmstrcopy() apparently copies the value of the 2nd parameter into the 1st parameter?
That appears to be a user-defined function. It is certainly not from the C standard library. If I were to guess based on the name and usage, I would guess that it copies a trimmed version of the string to which the right-hand argument points into the space to which the left-hand argument points.
I don't know where to find _TMC and TM_NLS_Get.
Those are not standard C features. Possibly they are recognized directly by your C implementation, or possibly they are macros defined earlier in the file or in one of the header files it includes.

Native Fortran type signature for "list of variable length strings"?

In Fortran, is there any way to declare an "array of allocatable arrays", that doesn't require wrapping the allocatable arrays into a derived type?
My main use-case would be to allow invoking a function with an array of variable-length strings, i.e. I am looking for a type signature matching the literal
["Hello", &
"World.", &
"How are you?"]
Motivation
In Fortran strings are natively represented as fixed-size character arrays, padded with blanks on the right. Arrays of strings are normally represented as arrays of (equal-length) character arrays, which I assume is in order to make them behave like a matrix of characters.
However, this also means that doing something like
CALL mySubroutine(["Hello","World.","How are you?"])
will result in a compiler error like
Error: Different CHARACTER lengths (5/4) in array constructor at (1)
A commonly suggested workaround (see e.g. Return an array of strings of different length in Fortran) is to use an array of derived types instead, e.g.
TYPE string
CHARACTER(LEN=:), ALLOCATABLE :: chars
END type string
! ...
CALL myStringSubroutine([string("Hello"), &
string("World."), &
string("How are you?")])
However, since there is no standardized string type of this kind, I am much more frequently seeing APIs using natively supported "workarounds" such as using fixed-size character strings, and trimming them when used. In this case the invocation would look like
CALL myFixedSubroutine(["Hello ", &
"World. ", &
"How are you?"])
While this is no problem in principle, it can become awkward and inefficient, if one of the strings is much longer than the others. It also has implications for version control, where now changing "... you?" to "... you??" means that the padding of the other lines has to be changed, creating spurious diffs.
(In the comments, a suggestion was given that at least automates the whitespace-padding.)
No, there is no way bar the wrapper type.
A fundamental concept in the language is that elements within an array may only vary in value. The allocation status of an object is not part of the value of that object.
(The allocation status of a component is part of the value of the object that has the component.)
A varying length string type is described in Part 2 of the Fortran standard.

Behaviour of char variables, what values are assigned and why? [duplicate]

I didn't know that C and C++ allow multicharacter literal: not 'c' (of type int in C and char in C++), but 'tralivali' (of type int!)
enum
{
ActionLeft = 'left',
ActionRight = 'right',
ActionForward = 'forward',
ActionBackward = 'backward'
};
Standard says:
C99 6.4.4.4p10: "The value of an
integer character constant containing
more than one character (e.g., 'ab'),
or containing a character or escape
sequence that does not map to a
single-byte execution character, is
implementation-defined."
I found they are widely used in C4 engine. But I suppose they are not safe when we are talking about platform-independend serialization. Thay can be confusing also because look like strings. So what is multicharacter literal's scope of usage, are they useful for something? Are they in C++ just for compatibility with C code? Are they considered to be a bad feature as goto operator or not?
It makes it easier to pick out values in a memory dump.
Example:
enum state { waiting, running, stopped };
vs.
enum state { waiting = 'wait', running = 'run.', stopped = 'stop' };
a memory dump after the following statement:
s = stopped;
might look like:
00 00 00 02 . . . .
in the first case, vs:
73 74 6F 70 s t o p
using multicharacter literals. (of course whether it says 'stop' or 'pots' depends on byte ordering)
I don't know how extensively this is used, but "implementation-defined" is a big red-flag to me. As far as I know, this could mean that the implementation could choose to ignore your character designations and just assign normal incrementing values if it wanted. It may do something "nicer", but you can't rely on that behavior across compilers (or even compiler versions). At least "goto" has predictable (if undesirable) behavior...
That's my 2c, anyway.
Edit: on "implementation-defined":
From Bjarne Stroustrup's C++ Glossary:
implementation defined - an aspect of C++'s semantics that is defined for each implementation rather than specified in the standard for every implementation. An example is the size of an int (which must be at least 16 bits but can be longer). Avoid implementation defined behavior whenever possible. See also: undefined. TC++PL C.2.
also...
undefined - an aspect of C++'s semantics for which no reasonable behavior is required. An example is dereferencing a pointer with the value zero. Avoid undefined behavior. See also: implementation defined. TC++PL C.2.
I believe this means the comment is correct: it should at least compile, although anything beyond that is not specified. Note the advice in the definition, also.
Four character literals, I've seen and used. They map to 4 bytes = one 32 bit word. It's very useful for debugging purposes as said above. They can be used in a switch/case statement with ints, which is nice.
This (4 Chars) is pretty standard (ie supported by GCC and VC++ at least), although results (actual values compiled) may vary from one implementation to another.
But over 4 chars? I wouldn't use.
UPDATE: From the C4 page: "For our simple actions, we'll just provide an enumeration of some values, which is done in C4 by specifying four-character constants". So they are using 4 chars literals, as was my case.
Multicharacter literals allow one to specify int values via the equivalent representation in characters. Useful for enums, FourCC codes and tags, and non-type template parameters. With a multicharacter literal, a FourCC code can be typed directly into the source, which is handy.
The implementation in gcc is described at https://gcc.gnu.org/onlinedocs/cpp/Implementation-defined-behavior.html . Note that the value is truncated to the size of the type int, so 'efgh' == 'abcdefgh' if your ints are 4 chars wide, although gcc will issue a warning on the literal that overflows.
Unfortunately, gcc will issue a warning on all multi-character literals if -pedantic is passed, as their behavior is implementation-defined. As you can see above, it is perhaps possible for equality of two multi-character literals to change if you switch implementations.
In C++14 specification draft N4527 section 2.13.3, entry 2:
... An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter literal, or an ordinary character literal containing a single c-char not representable in the execution character set, is conditionally-supported, has type int, and has an implementation-defined value.
Previous answers to your question pertained mostly on real machines that did support multicharacter literals. Specifically, on platforms where int is 4 bytes, four-byte multicharacter is fine and can be used for convenience, as per Ferrucio's mem dump example. But, as there is no guarantee that this will ever work or work the same way on other platforms, use of multicharacter literals should be deprecated for portable programs.
unbelievable, every compiler I know places the first character of a UINT defined as 4-character constant in the low significant byte (little indian) --- but Visual C does it in opposite direction 🙄
// file signature
#define SFKFILE_SIGNATURE 'SFPK' (S=53)
// check header
if (out_FileHdr->Signature != SFKFILE_SIGNATURE)
fails on VC:
Borland: 4B504653 4B504653
Watcom: 4B504653 4B504653
VisualC: 4B504653 5346504B

Compile Lua without automatic conversion between strings and numbers

Lua is generally a strongly-typed language, providing almost no implicit conversion between data types.
However, numbers and strings do get automatically coerced in a few cases:
Lua provides automatic conversion between string and number values at run time. Any arithmetic operation applied to a string tries to convert this string to a number, following the rules of the Lua lexer. (The string may have leading and trailing spaces and a sign.) Conversely, whenever a number is used where a string is expected, the number is converted to a string, in a reasonable format
Thus:
local x,y,z = "3","8","11"
print(x+y,z) --> 11 11
print(x+y==z) --> false
print(x>z) --> true
I do not want this. How can I recompile the Lua interpreter to remove all automatic conversion?
I would prefer to have:
print(x+y) --> error: attempt to perform arithmetic on a string value
print(x>1) --> error: attempt to compare number with string
print(x..1) --> error: attempt to concatenate a number value
The illustrious LHF has commented above that this is not possible out of the box, and requires editing the innards of Lua, starting with http://www.lua.org/source/5.2/lvm.c.html#luaV_tonumber
Marking this as the answer in order to close this question. If anyone later chooses to provide an answer with in-depth details on what needs to be done, I will gladly switch the acceptance mark to that answer.

Syntactic errors

I'm writing code for the exercise 1-24, K&R2, which asks to write a basic syntactic debugger.
I made a parser with states normal, dquote, squote etc...
So I'm wondering if a code snippet like
/" text "
is allowed in the code? Should I report this as an error? (The problem is my parser goes into comment_entry state after / and ignores the ".)
Since a single / just means division it should not be interpreted as a comment. There is no division operator defined for strings, so something like "abc"/"def" doesn't make much sense, but it should not be a syntax error. Figuring out if this division is possible should not be done by the parser, but be left for later stages of the compilation to be decided there.
That is syntactically valid, but not semantically. It should parse as the division operator followed by a string literal. You can't divide stuff by a string literal, so it's not legal code, overall.
Comments start with a two-character token, /*, and end with */.
As a standalone syntactical element this should be reported as an error.
Theoretically (as part of an expression) it would be possible to write
a= b /"text"; / a = b divided through address of string literal "text"
which is also wrong (you can't divide through a pointer).
But on the surface level would seem okay because it would syntactically decode as: variable operator variable operator constant-expression (address of string).
The real error would probably have to be caught in a deeper state of syntactical analysis (i.e. when checking if given types are suitable for the division operator).

Resources