I have inherited VFP code that has an IF Endif statement where the endif is coded ENDIF-*9 For whatever reason this gets past the compiler, and generates no run time errors. Anyone know why this works?
It is not specific to ENDIF. It would also work for endfor, enddo, endscan ... I think VFP only cares about seeing the word "endif" and discards rest as comment.
From the Help for DO WHILE ... ENDDO:
Comments can be placed after DO WHILE and ENDDO on the same line. The comments are ignored during program compilation and execution.
I've known that and always assumed that was the case. In your example, though, you're not leaving any space between the end of the keyword and the start of the 'extra' text. My guess would be that the lexer in VFP recognizes - (and I tested + as well) as a terminator for the ENDIF (or ENDDO, etc) and treats the rest of the line as a comment. If you just have extra stuff immediately after ENDIF (like ENDIFblah), VFP doesn't recognize the keyword and treats it as junk, resulting in a syntax error.
Related
This works:
$_ =
say "hi";
That is, you can put any amount of whitespace between an assignment and stuff that's behind, it will simply ignore it. You can use any variable (with my) too. Effectively, $_ will be assigned the result of the say, which is True.
Is this surprising, but up to spec, or simply surprising?
There may be any amount of whitespace either side of an operator. Thus:
say 1
+ 2
+ 3;
Is, so far as the compiler sees it, entirely the same as:
say 1 + 2 + 3;
Assignment (=) is just another operator, so also follows these rules.
Further, say is just a normal built-in subroutine, so it's just like:
my $answer = flip '24';
say $answer; # 42
Except with more whitespace:
my $answer =
flip '24';
say $answer; # 42
There are some places in Perl 6 where whitespace is significant, but the whitespace between infix operators is not one of them.
TL;DR P6 syntax is freeform.
Dangling topic (or any other) variable does not fail
The issue you describe is a very general one. It's most definitely not merely about variable declaration/assignment!
In P6, parsing of a statement -- a single imperative unit ("do this") -- generally just keeps on going until it reaches an explicit statement separator -- ; -- that brings a statement to its end, just like the period (aka full stop) at the end of this English sentence.
you can put any amount of whitespace
Like many programming languages, standard P6 is generally freeform. That is to say, wherever some whitespace is valid, then generally any amount of whitespace -- horizontal and vertical whitespace -- is syntactically equivalent.
$_ =
say "hi";
The above works exactly as would be expected if someone is applying the freeform principle -- it's a single statement assigning the value of the say to the $_ variable.
Is this surprising, but up to spec, or simply surprising?
I like inventing (hopefully pithy) sayings. I just invented "Surprise follows surmise".
It's up to spec. I know to expect it. It doesn't surprise me.
If someone embraces the fact that P6 is generally freeform and has semicolon statement separation then it will, I predict, (eventually -- likely quickly) stop being surprising.
The foregoing is a direct answer to your question. See also Jonathan's answer for more along the same lines. Feel free to ignore the rest of this answer.
For the rest of this answer I use "freeform" to refer to P6's combination of freeform syntax, semicolon statement separation, and braced blocks ({...}).
The rest of this answer is in three sections:
P6 exceptions to freeform syntax
Freeform vs line oriented
Freeform and line oriented?
P6 exceptions to freeform syntax
#Larry concluded that intuition, aesthetics, convenience, and/or other factors justified an exception from a pure freeform syntax in standard P6 in a few cases.
Statements may omit the trailing semicolon if they:
Are the last statement in a source file, or in a block;
End in a block whose closing curly is followed by a newline (ignoring comments).
Thus none of the three statements below (the if and two says) need a closing semicolon:
if 42 {
say 'no semicolon needed before the closing curly'
} # no semicolon needed after the closing curly
say 'no semicolon needed if last statement in source file'
Sometimes this may not be what's wanted:
{ ... } # the closing } ends the statement (block)
.() # call is invoked on $_
One way to change that is to use parentheses:
({ ... })
.() # calls the block on prior line
For some constructs spaces are either required or disallowed. For example, some postfixes must directly follow the values they apply to and some infixes must not. These are both syntax errors:
foo ++
foo«+»bar
Freeform vs line oriented
For some coding scenarios P6's freeform syntax is arguably a strong net positive, eg:
One liners can use blocks;
FP code is natural (one can write non-trivial closures);
More straight-forward editing/refactoring/copying/pasting.
But there are downsides:
The writing and reading overhead of freeform syntax -- semicolons and block braces.
Ignoring the intuition that presumably led you to post your question.
The latter is potent. All of the following could lead someone to think that the say in your example is part of a new statement that isn't a continuation of the $_ = statement:
The newline after the =;
The blank line after that;
The lack of an indent at the start of the say line relative to the $_ = line;
The nature of say (it might seem like say must be the start of a new statement).
An upshot of the above intuitions is that some programming languages adopt a "line-oriented" syntax rather than a freeform one, with the most famous being Python.1
Freeform and line oriented syntax
Some languages, eg Haskell, allow use of either line oriented or freeform syntax (at least for some language constructs).
P6 supports slangs, userland modules that mutate the language. Imagine a slang that supported both freeform and line-oriented code so:
Those learning P6 encountered more familiarity and less surprises as they learned the language's basics by focusing on either line-oriented or freeform code based on their preference;
Those familiar with P6 could write better code by using either line-oriented or freeform syntax.
At the risk of over-complicating things, imagine a slang that adopts not only line orientation but also the off-side rule that Python supports, and implements no strict; for untyped sigil-free variables (which drops declarators and sigils and promotes immutability). Here's a fragment of some code written in said imagined slang that I posted in a reddit comment a few weeks ago:
sub egg(bar)
put bar
data = ["Iron man", "is", "Tony Stark"]
callbacks = []
Perhaps something like the above is too difficult to pull off? (I don't currently see why.)
Footnotes
1 The remainder of this section compares P6 and Python using the Wikipedia section on Programming language statements as our guide:
A statement separator is used to demarcate boundaries between two separate statements.
In P6 it's ; or the end of blocks.
In Python ; is available to separate statements. But it's primarily line-oriented.
Languages that interpret the end of line to be the end of a statement are called "line-oriented" languages.
In Python a line end terminates a statement unless the next line is suitably indented (in which case it's the start of an associated sub-block) or an explicit line continuation character appears at the end of a line.
P6 is not line-oriented. (At least, not standard P6. I'll posit a P6 slang at the end of this answer that supports both freeform and line-oriented syntax.)
"Line continuation" is a convention in line-oriented languages [that] allows a single statement to span more than just one line.
Python has line continuation features; see the Wikipedia article for details.
Standard P6 also has line continuation features despite not being line-oriented.2
2 P6 supports line continuation. Continuing with quotes from Wikipedia:
a newline normally results in a token being added to the token stream, unless line continuation is detected.
(A token is the smallest fragment of code -- beyond an individual character -- that's treated as an atomic unit by the parser.)
Standard P6 always assumes a token break if it encounters a newline with the sole exception of a string written across lines like this:
say
'The
quick
fox';
This will compile OK and display The, quick, and fox on three separate lines.
The equivalent in Python will generate a syntax error.
Backslash as last character of line
In P6 a backslash:
Cannot appear in the middle of a token;
Can be used to introduce whitespace in sourcecode that is ignored by the parser to avoid what would otherwise be a syntax error. For example:
say #foo\
»++
Is actually a more general concept of "unspace" that can be used anywhere within a line not just at the end:
say #foo\ »++
Some form of inline comment serves as line continuation
This works:
say {;}#`( An embedded
comment ).signature
An embedded comment:
Cannot appear in the middle of a token;
Isn't as general as a backslash (say #foo#`[...]»++ doesn't work).
In a situation like this for example:
[% $create_port %]
or [list [% $RTL_LIST %]]
I realized it had to do with the brackets, but what confuses me is that sometimes it is used with the brackets and variable followed, and sometimes you have brackets with variables inside without the %.
So i'm not sure what it is used for.
Any help is appreciated.
% is not a metacharacter in the Tcl language core, but it still has a few meanings in Tcl. In particular, it's the modulus operator in expr and a substitution field specifier in format, scan, clock format and clock scan. (It's also the default prompt character, and I have a trivial pass-through % command in my ~/.tclshrc to make cut-n-pasting code easier, but nobody else in the world needs to follow my lead there!)
But the code you have written does not appear to be any of those (because it would be a syntax error in all of the commands I've mentioned). It looks like it is some sort of directive processing scheme (with the special sequences being [% and %], with the brackets) though not one I recognise such as doctools or rivet. Because a program that embeds a Tcl interpreter could do an arbitrary transformation to scripts before executing them, it's extremely difficult to guess what it might really be.
I am surprised when I run the following examples in ruby console. They both produce the same output.
"hello".length
and
"hello" .length
How does the ruby console remove the space and provide the right output?
You can put spaces wherever you want, the interpreter looks for the end of the line. For example:
Valid
"hello".
length
Invalid
"hello"
.length
The interpreter sees the dot at the end of the line and knows something has to follow it up. While in the second case it thinks the line is finished. The same goes for the amount of spaces in one line. Does it matter how the interpreter removes the spaces? What matters is that you know the behavior.
If you want you can even
"hello" . length
and it will still work.
I know this is not an answer to you question, but does the "how" matter?
EDIT: I was corrected in the comments below. The examples with multiple lines given above are both valid when run in a script instead of IRB. I was mixed them up with the operators. Where the following also applies when running a script:
Valid
result = true || false
Valid
result = true ||
false
Invalid
result = true
|| false
This doesn't have as much to do with the console as it has to do with how the language itself is parsed by the compiler.
Most languages are parsed in such a way that items to be parsed are first grouped into TOKENS. Then the compiler is defined to expect a certain SEQUENCE of tokens in order to interpret each programming statement.
Because the compiler is only looking for a TOKEN SEQUENCE, it doesn't matter if there is space in between or not.
In this case the compiler is looking for:
STRING DOT METHOD_NAME
So it won't matter if you write "hello".length, or even "hello" . length. The same sequence of tokens are present in both, and that is all that matters to the compiler.
If you are curious how these token sequences are defined in the Ruby source code, you can look at parse.y starting around line 1042:
https://github.com/ruby/ruby/blob/trunk/parse.y#L1042
This is a file that is written using the YACC language, which is a language used to define parsers with.
Even without knowing anything about YACC, you should already be able to get some clues on how it works by just looking around the file a bit.
I'm compiling my game engine code on VS2015 and Xcode using gcc.
I used many compilers for my code and only gcc shows the warning:
warning : missing terminating " character
The code is like following:
#if 1
...
#else
asm __volatile__("
some assembly code
...
"::: );
#endif
I know recent gcc does not accept new lines in a string but I don't know why gcc preprocessor spews warning for false block.
I know my writing style of inline assembly is old but they are in false conditional block. I don't want to touch them because there are so many.
How can I avoid this warning in false conditional block except suppressing all the warnings ?
Edit:
I compiled my code with Armcc, Vc++(2005,2008,2012,2013,2015) and clang. They don't show this kind of warning, only GCC does.
If the warnings are for the code in the TRUE conditional block, I will fix them. But this warnings are for FALSE conditional blocks which should not be evaluated.
C preprocessor is string-literal aware. Per language grammar, string literal is one of the preprocessing tokens
preprocessing-token:
header-name
identifier
pp-number
character-constant
string-literal
punctuator
each non-white-space character that cannot be one of the above
This is, of course, perfectly expected, since otherwise the preprocessor wouldn't be able to tell MACRO_NAME from "MACRO_NAME" (the latter being just a string).
For this reason, your string literals are supposed to be formatted properly for preprocessing purposes. I presume that GCC sees the first " and begins interpreting the sequence as a string literal, but then abandons the attempt (due to missing terminating ") and files it under the generic "cannot be one of the above" category, accompanying it with a warning,
You seem to be assuming that conditional inclusion works at the higher preprocessing level than recognition of such tokens as string literals. This assumption is incorrect. The preprocessor has no other choice but to parse the "disabled" stretch of the code as well.
I have a line of Fortran code, which includes some text. I'm changing the text, which makes the code line too long for Fortran, so I split it over two lines using 'a'.
Was:
IF (MYVAR .EQ. 1) THEN
WRITE(iott,'(A) (A)') 'ABC=', SOMEVAR
Changed to:
IF (MYVAR .EQ. 1) THEN
WRITE(iott,'(A) (A)') 'ABC DEF GHI JK
a ' // 'L=', SOMEVAR
My question is, on the new line (starting with 'a'), does the white space between the 'a' and the first ' get appended to the string? Or do I need the ' to be the char next to a to prevent additional white space?
As you can tell, I'm not used to Fortran...
If you're worried about exceeding a 72 column limit, then I assume you're using Fortran 77. The syntax for Fortran 77 requires that you start with column 7, except for continued lines, which need a continuation character in column 6. I use the following method to tell me how many lines are continued for one statement (the first line is just to show the columns):
!234567890
write(*,*)"Lorem Ipsum",
1 " Foo",
2 " Bar"
This would print:
Lorem Ipsum Foo Bar
You don't have to worry about spaces that aren't in quotes. All whitespace gets compressed in Fortran, anyway.
It's worthwhile learning how to use format statements. They can make output a lot easier. It's somewhat similar to printf statements, if you're coming from C. You specify a format with different types of parameters, then give variables or literals to fill out that format.
And don't worry that you're not working with the hot, new, language of the day. You can learn a lot from Fortran, even Fortran 77, and when used properly, Fortran can even be elegant. I've seen Fortran 77 written as if it were an object oriented language, complete with dynamic memory. I like to say, "old.ne.bad".
It's been too long for me to remember the old column requirements of FORTRAN (and they may not even be as strict as they were way back when).
But - isn't this something that a quick test run will tell you straight off?
Yes, the a is a continuation character and basically it just means append the rest of this line starting after the continuation character (col 6, right?) to the previous line.
Your Fortran compiler probably has an option to turn on "free form" input instead of using "fixed form" input. Use this and you won't have to worry about line length.
If your Fortran compiler is older than F90 -- which is when I think the free form input ability started, you have my condolences.
#Mike B:
In an ideal world yes, but in this case the code is developed on one machine, and submitted to a build server which has the appropriate 3rd party software / SDK's / licenses available to it to build. The build isn't exactly quick either.