Rebol - 69 or 7475 fully compliant with all rules
New working versions thanks to @rgchris! Not sure if the first fails the "don't access the source" requirement as the interpreter holds the loaded and parsed code it has been passed as a cmd line parameter in the system object (system/options/do-arg
) which is used to recognise itself.
probe not any[error? i: try[load/all input]i = system/options/do-arg]
This one follows all of the rules:
do b:[i: input prin block? if i <> join "do b:" mold b [try [load/all i]]]
Example usage:
First printing a valid integer, the second printing an invalid integer.
echo "rebol [] print 123" | rebol --do "probe not any[error? i: try[load/all input]i = system/options/do-arg]"
true
echo "rebol [] print 1w3" | rebol --do "probe not any[error? i: try[load/all input]i = system/options/do-arg]"
false
echo "probe not any[error? i: try[load/all input]i = system/options/do-arg]" | rebol --do "probe not any[error? i: try[load/all input]i = system/options/do-arg]"
false
Fully compliant version:
echo 'rebol [] 123' |r3 --do 'do b:[i: input prin block? if i <> join "do b:" mold b [try [load/all i]]
true
echo 'rebol [] 123a' |r3 --do 'do b:[i: input prin block? if i <> join "do b:" mold b [try [load/all i]]]'
false
echo 'do b:[i: input prin block? if i <> join "do b:" mold b [try [load/all i]]]' |r3 --do 'do b:[i: input prin block? if i <> join "do b:" mold b [try [load/all i]]
false
Explanation:
First version
This uses Rebols built-in load
function to parse and load the code from stdin but it does not execute it.
The try
block catches any syntax errors and the error?
function converts the error to a simple boolean.
The i = system/options/do-arg
compares the input from stdin (assigned to i
) with the code passed on the do-arg
argument (sneaky but very golf :).
any
is a great function which returns true
if any
-thing in the block evaluates to true
(for example, any [ false false true ]
would return true
).
not
then just inverts the boolean to give us the correct answer and probe
displays the contents of the returned value.
Fully compliant version
Let's go through this in order ...
Assign the word b
to the block [] that follows.
Use the do
function to interpret the do
dialect in the b
block.
Inside the b
block ...
Set the word i
to refer to the contents of stdin (input
).
Now, if
we join
the string "do b:" to the mold
'ed block b
and it is not equal (<>
) to the stdin input i
then we try to load
the input i
.
If the result is a block
then we have load
'ed the passed data correctly otherwise we would receive a none
from the failed if
.
Use prin
to display the result of block?
which returns true if the result is a block. Using prin
as opposed to print
does not display a carriage return after the output (and it saves us another char).
1Is using standard and/or 3rd-party libraries allowed? (specifically, to use a working lexer/parser for your language) – Martin Ender – 2014-07-04T19:02:22.047
Is
try:exec(raw_input())...
allowed? – user80551 – 2014-07-04T19:07:00.467@user80551 That won't work for syntactically correct input which loops forever. It's also a slight security risk. – Martin Ender – 2014-07-04T19:12:36.580
Shouldn't it have the quine tag? – Sylwester – 2014-07-04T19:12:49.453
1@m.buettner What if we indent raw_input() into a new function and exec it so that the function is never actually called. BTW who he heck cares about security risks in code-golf? – user80551 – 2014-07-04T19:18:46.980
@user80551 Well that kind of security risk would prevent the code from working in all cases, because the executed code might crash the computer, kill the process, etc. Wrapping the code into something that's never executed and then calling
exec
sounds like a decent idea though! :) – Martin Ender – 2014-07-04T19:20:05.410@Sylwester Its not quite a quine, since you don't technically have to produce the code. In fact, you could just put in a syntax error (according to, say, your language's standard) as long as it is ignored by the compiler (and therefore run-able.) – PyRulez – 2014-07-04T23:31:46.437
@PyRulez I don't think that would work, because then there would be other programs which would exhibit the same behaviour. To actually make the program behave differently only on itself, I'm pretty sure you'll have to use quine techniques in that you need to check the input against some string which happens to be equal to your own source code (like Ventero did). – Martin Ender – 2014-07-05T14:00:17.250