Checking if the argument for a program is empty? - command-line

I run a program compiled from Fortran source:
./a.out N t
Here N and t define two positive integer numbers. Here is the code for this:
character(len=10) :: arg
call get_command_argument(1, arg)
read(arg,'(I10)') N
call get_command_argument(2, arg)
read(arg,'(I10)') t
Next, I want to do following: if I don't enter neither N nor t (i.e., if arg,1 is empty), then the program proposes enter them through program (I don't know what is the analog of scanf in Fortran). How to do that explicitly, could You help?

If I understand it correctly, you are looking for something like
character(len=10) :: arg
call get_command_argument(1, arg)
if (trim(arg) == '') then
write(*,*) 'Please enter N:'
read(*,*) N
else
read(arg,'(I10)') N
end if
call get_command_argument(2, arg)
if (trim(arg) == '') then
write(*,*) 'Please enter t:'
read(*,*) t
else
read(arg,'(I10)') t
end if

1) Your code (namely get_command_argument) is no way Fortran 77, but Fortran 2003.
2) Just use command_argument_count() to find out how many arguments you got.
if (command_argument_count()==0) then
do whatever you need to do

Related

Ada - Commando- line reader and processer

A program that loads and processes command-line arguments should be created.
Here comes a few examples on how it should look when you run it (bold text is the text that the user will type):
Terminal prompt % **./my_program**
No arguments given.
Terminal prompt % **./my_program 123**
Wrong amounts of arguments given.
Terminal prompt % **./my_program 10 XYZ 999 Greetings!**
Wrong amounts of arguments given.
Terminal prompt % **./my_program 3 HELLO**
Message: HELLOHELLOHELLO
The program "./my program" is ending.
Terminal prompt % **./my_program 0 Bye**
Message:
The program "./my program" is ending.
This is my code so far:
with Ada.Text_IO; use Ada.text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Command_Line; use Ada.Command_Line;
procedure my_program is
type String is array (Positive) of Character;
N : Integer;
Text : String;
begin
N := Argument_Count;
if N = 0 then
Put_Line("No arguments given.");
elsif N /= 2 then
Put_Line("Wrong number of arguments given.");
elsif N = 2 then
Put("Message: ");
for I in 1 .. N loop
Put(Text);
New_Line;
end loop;
Put("The program """);
Put(""" is ending. ");
end if;
end my_program;
My program handles the first 3 three cases but when I go ahead with the 4th and 5th (last) case I get an error code at the row Put(Text) where it says
Missing argument for parameter "Item" in call to "Put"
I don't know if I declared my string right because I don't want a string of a specific length. Can anyone come up with something that could help me solve case 4 and 5? It would be nice and highly appreciated
This seems to be a homework or exam question, so I would usually not provide a full answer. But Chris already gave that (with some defects), so here is my suggestion. Compared to Chris's solution, I try to avoid using unnecessary variables, and I favour case statements over if-then-else cascades, and I try to reduce the scope of exception handlers. I prefer to put use clauses in the subprogram so that the context-clause section contains only with clauses. I use the string-multiplying "*" operator from Ada.Strings.Fixed, but that is perhaps an unnecessary refinement.
with Ada.Command_Line;
with Ada.Strings.Fixed;
with Ada.Text_IO;
procedure My_Program
is
use Ada.Strings.Fixed;
use Ada.Text_IO;
begin
case Ada.Command_Line.Argument_Count is
when 0 =>
Put_Line ("No arguments given.");
when 2 =>
begin
Put_Line (
Natural'Value (Ada.Command_Line.Argument(1))
* Ada.Command_Line.Argument(2));
exception
when Constraint_Error =>
Put_Line ("Invalid input for argument 1.");
end;
when others =>
Put_Line ("Wrong amount of arguments given.");
end case;
Put_Line (
"The program """
& Ada.Command_Line.Command_Name
& """ is ending.");
end My_Program;
Note that my version:
Rejects negative first arguments (like "-3").
Outputs the repeated strings on a single line, as was required by the examples given.
Includes the name of the program in the final message, as was also required.
Given the clarification in comments as to the purpose of the program, to print a message n times where n is the first argument, and the message is the second argument, you need to parse the first argument as an integer. This can be done with Integer'Value.
Now, that raises the prospect of the user not running the program with an integer. So we have to handle the possible Constraint_Error exception.
with Ada.Text_IO; use Ada.text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Command_Line; use Ada.Command_Line;
procedure my_program is
argc : Integer;
N : Integer;
begin
argc := Argument_Count;
if argc = 0 then
Put_Line("No arguments given.");
elsif argc /= 2 then
Put_Line("Wrong number of arguments given.");
else
n := Integer'Value(Argument(1));
Put("Message: ");
for I in 1 .. N loop
Put_Line(Argument(2));
end loop;
Put("The program """);
Put(""" is ending. ");
end if;
exception
when Constraint_Error =>
Put_Line("Invalid input for argument 1.");
end my_program;
As an aside, when we've checked in our conditional if argc is zero, and that it doesn't equal two, we don't have to use elsif. The only other possibility is that it is 2.
You say
My program handles the first 3 three cases but when I go ahead with the 4th and 5th (last) case I get an error code at the row Put(Text) where it says "Missing argument for parameter "Item" in call to "Put". "
which doesn't make sense, because your program as shown doesn't compile. I guess what you mean is "when I try to add the code to handle cases 4 and 5, it doesn't compile".
The reason why it doesn’t compile is hidden in the actual error messages:
leun.adb:24:10: no candidate interpretations match the actuals:
leun.adb:24:10: missing argument for parameter "Item" in call to "put" declared at a-tiinio.ads:97, instance at a-inteio.ads:18
...
leun.adb:24:14: expected type "Standard.Integer"
leun.adb:24:14: found type "String" defined at line 7
leun.adb:24:14: ==> in call to "Put" at a-tiinio.ads:80, instance at a-inteio.
You have at line 7
type String is array (Positive) of Character;
which is both misleading and not what you meant.
It’s ’not what you meant’ because array (Positive) means an array of fixed length from 1 to Positive’Last, which will not fit into your computer’s memory. What you meant is array (Positive range <>).
Even with this correction, it's 'misleading' because although it would be textually the same as the declaration of the standard String in ARM 3.6.3(4), in Ada two different type declarations declare two different types. So, when you write Put(Text); the Put that you meant to call (the second in ARM A.10.7(16)) doesn’t match because it’s expecting a parameter of type Standard.String but Text is of type my_program.String.
Cure for this problem: don’t declare your own String type.

Why does one of these semingly equivalent macros fail?

Consider these two macro definitions:
macro createTest1()
quote
function test(a = false)
a
end
end |> esc
end
macro createTest2()
args = :(a = false)
quote
function test($args)
a
end
end |> esc
end
According to the builtin Julia facilities they should both evaluate to the same thing when expanded:
println(#macroexpand #createTest1)
begin
function test(a=false)
a
end
end
println(#macroexpand #createTest2)
begin
function test(a = false)
a
end
end
Still I get a parse error when trying to evaluate the second macro:
#createTest2
ERROR: LoadError: syntax: "a = false" is not a valid function argument name
It is a space in the second argument list. However, that should be correct Julia syntax. My guess is that it interprets the second argument list as another Julia construct compared to the first. If that is the case how do I get around it?
The reason that the second macro is failing as stated in my question above. It looks correct when printed however args is not defined correctly and Julia interprets it as an expression which is not allowed. The solution is to instead define args according to the rules for function parameters. The following code executes as expected:
macro createTest2()
args = Expr(:kw, :x, false)
quote
function test($(args))
a
end
end |> esc
end

How to create a Lisp FLI function corresponding to a C macro

I want to create a lisp function which corresponds to a macro in C.
e.g., there is one HIWORD in win32 API, which is defined as a macro in the header file.
I tried to define it as below but was told that HIWORD is unresolved.
CL-USER 4 > (hiword #xFFFFFFFF)
Error: Foreign function HIWORD trying to call to unresolved external function "HIWORDW".
I just want to know how to create a wrapper for C macros like for C functions.
(fli:define-c-typedef DWORD (:unsigned :long))
(fli:define-c-typedef WORD (:unsigned :short))
(fli:define-foreign-function
(HIWORD "HIWORD" :dbcs)
((dwVal dword))
:result-type word :calling-convention :stdcall)
You cannot do this directly. C preprocessor macros are not preserved in the compilation process, i.e., there is simply no artifact in the generated object files, which would correspond to the C macro itself (though its expansion may be part of the object file multiple times). And since there is no artifact, there is nothing to bind to with FFI.
You can, however, provide a wrapper function
#define HIGHWORD(x) /* whatever */
int
highword_wrapper(int x)
{
return HIGHWORD(x);
}
and this one can be used with FFI.
No need to jump into another language. Shifting and masking in Lisp:
(defun hiword (val)
(logand (ash val -16) #xFFFF)
(defun loword (val) ;; ditto
(logand val #xFFFF))
Another way: using the ldb accessor with ranges expressed using byte syntax:
(defun hiword (val)
(ldb (byte 16 16) val) ;; get 16-bit-wide "byte" starting at bit 16.
(defun loword (val)
(ldb (byte 16 0) val) ;; get 16-bit-wide "byte" at position 0.

Julia: inject code into function

I would like to inject code into a function. For concreteness, consider a simple simulater:
function simulation(A, x)
for t in 1:1000
z = randn(3)
x = A*x + z
end
end
Sometimes I would like to record the values of x every ten time-steps, sometimes the values of z every 20 time-steps, and sometimes I don't want to record any values. I could, of course, put some flags as arguments to the function, and have some if-else statements. But I would like to rather keep the simulation code clean, and only inject a piece of code like
if t%10 == 0
append!(rec_z, z)
end
into particular places of the function whenever I need it. For that, I'd like to write a macro such that monitoring a particular value becomes
#monitor(:z, 10)
simulation(A, x)
Is that possible with Julia's Metaprogramming capabilities?
No, you cannot use metaprogramming to inject code into an already-written function. Metaprogramming can only do things that you could directly write yourself at precisely the location where the macro itself is written. That means that a statement like:
#monitor(:z, 10); simulation(A, x)
cannot even modify the simulation(A, x) function call. It can only expand out to some normal Julia code that runs before simulation is called. You could, perhaps, include the simulation function call as an argument to the macro, e.g., #monitor(:z, 10, simulation(A, x)), but now all the macro can do is change the function call itself. It still cannot "go back" and add new code to a function that was already written.
You could, however, carefully and meticulously craft a macro that takes the function definition body and modifies it to add your debug code, e.g.,
#monitor(:z, 10, function simulation(A, x)
for t in 1:1000
# ...
end
end)
But now you must write code in the macro that traverses the code in the function body, and injects your debug statement at the correct place. This is not an easy task. And it's even harder to write in a robust manner that wouldn't break the moment you modified your actual simulation code.
Traversing code and inserting it is a much easier task for you to do yourself with an editor. A common idiom for debugging statements is to use a one-liner, like this:
const debug = false
function simulation (A, x)
for t in 1:1000
z = rand(3)
x = A*x + z
debug && t%10==0 && append!(rec_z, z)
end
end
What's really cool here is that by marking debug as constant, Julia is able to completely optimize away the debugging code when it's false — it doesn't even appear in the generated code! So there is no overhead when you're not debugging. It does mean, however, that you have to restart Julia (or reload the module it's in) for you to change the debug flag. Even when debug isn't marked as const, I cannot measure any overhead for this simple loop. And chances are, your loop will be more complicated than this one. So don't worry about performance here until you actually double-check that it's having an effect.
You might be interested in this which i just whipped up. It doesn't QUITE do what you are doing, but it's close. Generally safe and consistent places to add code are the beginning and end of code blocks. These macros allow you to inject some code in those location (and even pass code parameters!)
Should be useful for say toggle-able input checking.
#cleaninject.jl
#cleanly injects some code into the AST of a function.
function code_to_inject()
println("this code is injected")
end
function code_to_inject(a,b)
println("injected code handles $a and $b")
end
macro inject_code_prepend(f)
#make sure this macro precedes a function definition.
isa(f, Expr) || error("checkable macro must precede a function definition")
(f.head == :function) || error("checkable macro must precede a function definition")
#be lazy and let the parser do the hard work.
b2 = parse("code_to_inject()")
#inject the generated code into the AST.
unshift!(f.args[2].args, b2)
#return the escaped function to the parser so that it generates the new function.
return Expr(:escape, f)
end
macro inject_code_append(f)
#make sure this macro precedes a function definition.
isa(f, Expr) || error("checkable macro must precede a function definition")
(f.head == :function) || error("checkable macro must precede a function definition")
#be lazy and let the parser do the hard work.
b2 = parse("code_to_inject()")
#inject the generated code into the AST.
push!(f.args[2].args, b2)
#return the escaped function to the parser so that it generates the new function.
return Expr(:escape, f)
end
macro inject_code_with_args(f)
#make sure this macro precedes a function definition.
isa(f, Expr) || error("checkable macro must precede a function definition")
(f.head == :function) || error("checkable macro must precede a function definition")
#be lazy and let the parser do the hard work.
b2 = parse(string("code_to_inject(", join(f.args[1].args[2:end], ","), ")"))
#inject the generated code into the AST.
unshift!(f.args[2].args, b2)
#return the escaped function to the parser so that it generates the new function.
return Expr(:escape, f)
end
################################################################################
# RESULTS
#=
julia> #inject_code_prepend function p()
println("victim function")
end
p (generic function with 1 method)
julia> p()
this code is injected
victim function
julia> #inject_code_append function p()
println("victim function")
end
p (generic function with 1 method)
julia> p()
victim function
this code is injected
julia> #inject_code_with_args function p(a, b)
println("victim called with $a and $b")
end
p (generic function with 2 methods)
julia> p(1, 2)
injected code handles 1 and 2
victim called with 1 and 2
=#

Can you return nothing from a function in Scheme?

I'm writing a scheme interpreter, and in the case of an if statement such as:
(if (< 1 0) 'true)
Any interpreter I've tried just returns a new prompt. But when I coded this, I had an if for whether there was an alternative expression. What can I return in the if such that nothing gets printed?
(if (has-alternative if-expr)
(eval (alternative if-expr))
#f) ;; what do I return here?
According to the R6RS specification:
If <test> yields #f and no <alternate>
is specified, then the result of the
expression is unspecified.
So go wild, return anything you want! Although #f or '() are what I, personally, would expect.
Scheme can indeed return no values:
> (values)
In R5RS the one-armed form of if is specified to return an unspecified value.
That means it is up to you, to decide which value to return.
Quite a few Schemes have chosen to introduce a specific value called
"the unspecified value" and returns that value.
Others return "the invisible value" #<void> and the REPL is written
such that it doesn't print it.
> (void)
At first one might think, this is the same as (values),
but note the difference:
> (length (list (void)))
1
> (length (list (values)))
error> context expected 1 value, received 0 values
(Here (list ...) expected 1 value, but received nothing)
If #<void> is part of a list, it is printed:
> (list (void))
(#<void>)
A number of Schemes (PLT, Ikarus, Chicken) have a void type, which you can produce with (void).
In PLT at least, void is what you get when you do (when (< 1 0) #t).
(PLT v4 doesn't allow if without an else clause.)
When the return value is unspecified you can return what you like; the user just can't rely on that value being there, ever, or across implementations.
First, it's OK to require if to have an else clause, if it makes it easier for you. Second, Scheme supports returning multiple values from a function, so if you were to implement the return values as a list, you could have an empty list signify that no return value was given.
(if (has-alternative if-expr)
(eval (alternative if-expr)) ; make sure eval returns a list
'())
An important distinction here: I'm not returning an empty list if there was no else clause. The empty list signifies that there was no return value. If there were one return value from an expression (say it was 3) you would have (3) as the return from the eval behind the scenes. Similarly, returning multiple values from an expression would cause the eval return list to have multiple elements.
Finally, in all practicality, you could really return anything if the condition fails and there's no else, because it would be an error in a program to attempt to capture the value of a function that doesn't return anything. As such, it would be the job of the programmer, not the language, to catch this error.
Weird people would return 'nil or '|| (the empty symbol). The problem is to return a symbol that cannot be return by (eval (alternative if-expr)) to avoid confusion.
If anything can be returned by (eval (alternative if-expr)) and you still want to know whether you came in this alternative or not, you have to pack the result with more information :
(if (has-alternative if-expr)
(cons #t (eval (alternative if-expr)))
(cons #f #f))
Thus, the result is a cons cell. If its car is #t, then you evaled something. If it is #f, you didn't.
What is wrong with just:
(if (has-alternative if-expr) (eval (alternative if-expr)))
?