I'm trying to compile this Calculator.ada file using gcc -c Calculator.ada and receive the error warning: Calculator.ada: linker input file unused because linking not done -- I've tried looking up solutions and downloading other things that may compile this for me but haven't figured it out yet....
Here is Calculator.ada:
--
-- Integer calculator program. Takes lines of input consisting of
-- <operator> <number>, and applies each one to a display value. The
-- display value is printed at each step. The operator is one of =,
-- +, -, *, /, or ^, which correspond to assign, add, subtract, multiply
-- divide, and raise, respectively. The display value is initially zero.
-- The program terminates on a input of q.
--
with Text_IO;
with Gnat.Io; use Gnat.Io;
procedure Calc is
Op: Character; -- Operation to perform.
Disp: Integer := 0; -- Contents of the display.
In_Val: Integer; -- Input value used to update the display.
begin
loop
-- Print the display.
Put(Disp);
New_Line;
-- Promt the user.
Put("> ");
-- Skip leading blanks and read the operation.
loop
Get(Op);
exit when Op /= ' ';
end loop;
-- Stop when we're s'posed to.
exit when Op = 'Q' or Op = 'q';
-- Read the integer value (skips leading blanks) and discard the
-- remainder of the line.
Get(In_Val);
Text_IO.Skip_Line;
-- Apply the correct operation.
case Op is
when '=' => Disp := In_Val;
when '+' => Disp := Disp + In_Val;
when '-' => Disp := Disp - In_Val;
when '*' => Disp := Disp * In_Val;
when '/' => Disp := Disp / In_Val;
when '^' => Disp := Disp ** In_Val;
when '0'..'9' => Put_Line("Please specify an operation.");
when others => Put_Line("What is " & Op & "?");
end case;
end loop;
end Calc;
I would appreciate any assistance as to why I can't compile this. I'm able to compile C files fine with gcc -c and read that I can compile the same way for Ada.
Since gcc only recognizes .ads and .adb as file endings for Ada sources (as explained in this link mentioned by Eugene), you need to tell it explicitly that you want this file to be compiled as Ada source. You can do this via
gcc -x ada -c Calculator.ada
The compiler will then probably give a warning like
Calculator.ada:11:11: warning: file name does not match unit name, should be "calc.adb"
but you can ignore that. However, best practice would be to use the file names expected by gcc.
By default, Ada source file need to end with .ads (for package specs) or .adb (for bodies), and file names need to match the top-level entity they contain. In your case, you should use calc.adb.
If you have more complex source files containing multiple entities, you can use the gnatchop tool to rename source files.
Under File Naming Topics and Utilities, the manual contains much more documentation how source code can be represented in the file system.
Related
I'm trying to write a CMake script that does the following:
Using the execute_process instruction reads the output of a command and stores it into a variable named 'STRING_VARIABLE'. The command that returns something that has both characters and digits in it's name. Something like this: RESULT-v1.2.8-...
I have read this value properly and displayed it on the terminal to confirm this.
Now what I want to do is store the first three digits of this output and store them in 3 other variables: 'FIRST_DIGIT', 'SECOND_DIGIT' and 'THIRD_DIGIT'.
My logic was this:
Using a counter count each time a digit is encountered in a variable name. Each time a digit is encountered store the digit in one of the three variables then increment the counter. The counter counts therefore from 0 to 2 and for each of these 3 values does a store.
Here is the script I wrote:
SET(COUNTER 0)
foreach(LETTER ${STRING_VARIABLE})
if(LETTER EQUAL '0,1,2,3,4,5,6,7,8,9')
if( COUNTER EQUAL 0 ) # if first digit is encountered
list(GET STRING_VARIABLE LETTER FIRST_DIGIT) # store it in FIRST_DIGIT
SET(COUNTER 1)
elseif( COUNTER EQUAL 1 ) # if second digit is encountered
list(GET STRING_VARIABLE LETTER SECOND_DIGIT) # store it in SECOND_DIGIT
SET(COUNTER 2)
else( COUNTER EQUAL 2 ) # if second digit is encountered
list(GET STRING_VARIABLE LETTER THIRD_DIGIT) # store it in THIRD_DIGIT
endif()
endif()
endforeach()
# To check the variables
#message("*****${STRING_VARIABLE}") # OK!
message("*****${FIRST_DIGIT}") # NOT OK :(
As I'm a total beginner in CMake I suppose my problem is at either of the two(or both):
- When looping through the 'STRING_VARIABLE' I used foreach(LETTER) and since my string also contains digits the program may not see them. If that is the mistake with what else should I replace LETTER in order to get each character of the string?
- In the first if where I check if the 'LETTER' is a digit. I think that is the correct syntax altough I'm not sure. Basically what I'm doing there is trying to check if the letter at each index is a digit.
The 'STRING_VARIABLE' prints ok as I said.
However when I try printing the 'FIRST_DIGIT' or any other of the 3(second and third) I get an empty string as a result.
Please help me understand what is wrong in my logic and what I'm doing wrong.
Please help me understand what I'm doing wrong. Thank you.
In case the format is know, you can use string(REGEX REPLACE ...).
Function:
function(get_versions versionstring libname major minor patch)
string(REGEX REPLACE "([A-Za-z0-9_]*)-[vV].*" "\\1" locallibname ${versionstring} )
set(libname ${locallibname} PARENT_SCOPE)
string(REGEX REPLACE "^([A-Za-z0-9_]*-[vV])([0-9]*)([.][0-9]*[.][0-9]*-?.*)$" "\\2" numbers ${versionstring} )
set(major ${numbers} PARENT_SCOPE)
string(REGEX REPLACE "^([A-Za-z0-9_]*-[vV][0-9]*[.])([0-9]*)([.][0-9]*-?.*)$" "\\2" numbers ${versionstring} )
set(minor ${numbers} PARENT_SCOPE)
string(REGEX REPLACE "^([A-Za-z0-9_]*-[vV][0-9]*[.][0-9]*[.])([0-9]*)(-?.*)$" "\\2" numbers ${versionstring} )
set(patch ${numbers} PARENT_SCOPE)
endfunction()
Usage:
get_versions("MyLib-V11.222.034-remark" libname major minor patch)
status_ref(libname)
status_ref(major)
status_ref(minor)
status_ref(patch)
Result:
STATUS: libname = "MyLib"
STATUS: major = "11"
STATUS: minor = "222"
STATUS: patch = "034"
Im just starting up with pascal and I'm doing the good old bhaskara solver with the following code:
Program bhaskara;
var
a,b,c: real;
begin
writeln('Ingrese a, b y c');
readln(a,b,c);
if sqr(b) >= 4*a*c then
begin
writeln('tiene raices reales');
end
else
begin
writeln('no tiene raices reales');
end
readln(a);
end.
The last line: readln(a), which is there just to pause the program and see the output is making the program not compile(program works fine without it), it says:
bhaskara.pas(15,2) Fatal: Syntax error, ";" expected but "identifier READLN" found
Im sure it's something simple but i can't find the answer, please help.
Pascal requires a semicolon as a statement separator between statements.
Your else block is a statement and because it is not the final line
of the program and is followed by your readln(a), it requires a ';'
after it.
In fact, because your else clause contains only a single statement,
it does not require the begin & end.
So you could simply write
else
writeln('no tiene raices reales');
readln(a);
You need a semicolon (;) after the "end" statement right before the readln statement.
I would like to make a VHDL procedure that closes and opens a file again. Although the procedure would do other things as well, this operation essentially rewinds the file to the beginning.
However, I'm not finding a way to get back to the filename from the file handle.
eg:
process
procedure close_and_open(file F : text) is
begin
file_close(F);
file_open(F, "HERE_LIES_THE_PROBLEM", read_mode);
end procedure
file Fi : text;
begin
file_open(Fi, "example_file.txt", read_mode);
close_and_open(Fi);
wait;
end process;
It seems that Fi'simple_name, instance_name and path_name only refer to the name "Fi" in this case, not the name of the file itself. Naturally, it would be possible to pass the filename as second argument, but it this case it would not be very straight-forward (filenames have run-time generated elements).
Your 'file handle' handle in your example is a string literal.
IEEE Std 1076-2008 5.5.2 File operations depend on IEEE Std 1003.1-2004 Portable Operating System Interface (POSIX) - see Annex J. There is no 1003.1 POSIX way to recover the pathname from a file descriptor (represented in VHDL by the FILE object).
In your code there is no way to recover the file logical name from a file declaration or external_name from a file_open procedure when supplied by a literal string expression. There's no named object to evaluate.
You can manipulate a string expression at run time by allocating it's value to an object of an access type of type string. This provides an object name that denotes a string object.
Leaving the file name argument out of your procedure call is a scope and visibility declaration order exercise due to variable class of an object of an access type. The value of the denoted object is accessed by selected name with the suffix all (8.3 Selected names paragraph 5).
Constructing a Minimal Complete and Verifiable example:
use std.textio.all;
entity close_open is
end entity;
architecture foo of close_open is
begin
NOTLABELED:
process
type filename is access string; -- ADDED
variable file_name: filename; -- ADDED
procedure close_and_open(file F : text) is
begin -- ADDED
file_close(F);
-- file_open(F, "HERE_LIES_THE_PROBLEM", read_mode);
file_open(F, file_name.all, read_mode); -- CHANGED
end procedure;
file Fi : text;
begin
file_name := new string'("example_file.txt"); -- ADDED
-- file_open(Fi, "example_file.txt", read_mode);
file_open(Fi, file_name.all, read_mode); -- CHANGED
close_and_open(Fi);
wait; -- ADDED
end process;
end architecture;
There's a declaration order dependency between the access type declaration, the declaration of a variable of the access type and the procedure body.
This example analyzes, elaborates and runs (which requires the file_name be capable of being opened for read).
A wait statement has been added to prevent the process from opening and closing the file without end. There was also a missing begin in your procedure body.
im new using Pascal and i have to program a game called seven eleven, can you guys give me some tips?
Ive tried:
program sevele;
var capitalinicial: integer
begin
writeln('ingrese un capital')
readln(capitalinicial)
writeln('su capital es capitalinicial')
Answering your question, There are a few things you need to know:
You have to put a semicolon ; at the end of every sentence, except after a keyword that denotes the beginning of a control structure (for,while,if,else,etc) or after a begin or end keyword.
Use the same amount of begins and ends keywords. Note that the last end in the program is followed by a dot.
When you use writeln you can print one or more variables or strings. You have to use simple quotes ' to print strings, and just the name of a variable without any quote to print it's value, also you need to separe the diferent arguments with commas ','.
for example:
program example;
var
a,b:integer;
begin
a:=3;
b:=5;
writeln ('this is just a string');
writeln (a);
writeln (a,b);
writeln ('the value of a is: ',a,' and the value of b is: ',b);
readln;
end.
The code you attemped to write probably is:
program sevele;
var capitalinicial: integer;
begin
writeln('ingrese un capital');
readln(capitalinicial);
writeln('su capital es ',capitalinicial);
readln; //use this to give you time to view the output
end.
This is how it works
program sevele;
var capitalinicial: integer;
begin
writeln('ingrese un capital');
readln(capitalinicial);
writeln('su capital es',capitalinicial);
end.
Reading this Pascal BNF grammar I can't understand why is a ; required to appear after end in a function definition. After a function-heading is seen, a function-block that's block may appear:
function-declaration =
function-heading ";" function-body |
function-heading ";" directive |
function-identification ";" function-body .
function-body =
block .
When a begin appear, that's part of a statement-par, that's part of a block, it's processed by statement-part, right?
block =
declaration-part statement-part .
statement-part =
begin statement-sequence end .
Note statement-part. There's no ; here after end keyword and this is not part of a statement-sequence. So, I don't get how the compiler claims about lack of ; after end keyword, like in this example:
function myabs(i : integer) : integer;
begin
if i < 0 then begin i := -i; end; < -- it's process by statement-sequence, so, ';' may appear
myabs := i;
end; <-- it is the semicolon what about I'm speaking
What am I missing? am I reading wrong the grammar? all Pascal compilers I've tried give an error if I omit this.
ANTLRWorks is your best friend here.
If you try some pascal grammar such as http://www.monperrus.net/martin/pascal-antlr3 using antlrworks (http://www.antlr3.org/works/) you'll see that a program like
program first;
function myabs(i : integer) : integer;
begin
end;
begin
end.
will be parsed like this
so you can see exactly what's happening.
ps. the pascal grammar link I've provided to you has a problem with one specific token, but I bet you can workaround this ;-)
ps2. update - antlrworks screenshot to help #Jack
You don't have to have a semi-colon after an end. Simple as that.
Semi-colon is used to separate statements. So you only need to have a semi-colon after an end if it is not the last statement. If it is the last statement you should instead have a full stop.
Now, there could also be some error in the BNF that means that according to the BNF you don't have to have a semi-colon where you actually need it, but the only way to figure that out is to analyze the whole BFN in detail, which I don't feel is constructive. :-)
But in this case I think what you have missed is that a procedure or function declaration must end with a semi-colon.
Procedure and functions do not need to be terminated with a semi-colon, but they must be separated by one:
From the Pascal BNF
proc-and-func-declaration:
proc-or-func
proc-and-func-declaration ; proc-or-func