I'm new to OCaml and I am a little confused about Modules.
I tried to implement a really simple test but I can't compile it...
Here are the files (I'm on Linux by the way) :
main.ml
let main () =
if ((Array.length Sys.argv) > 2 && int_of_string Sys.argv.(1) > 1 && int_of_string Sys.argv.(2) > 1)
then
begin
Printf.printf "Args = %d && %d\n" (int_of_string Sys.argv.(1)) (int_of_string Sys.argv.(2));
Laby.initLaby (int_of_string Sys.argv.(1)) (int_of_string Sys.argv.(2))
end
else
Printf.printf "Usage : ./test x y n"
let _ = main ()
Laby.ml
let initLaby (x : int) (y : int) =
let testCell = Cell.initCell 0 1 in
begin
Printf.printf "Init Laby with X(%d) / Y(%d)\n" x y;
Cell.printCell testCell;
end
Cell.ml
module type CELL =
sig
type t
val initCell : int -> int -> t
val printCell : t -> unit
end
module Cell : CELL =
struct
type t = (int * int)
let initCell (x : int) (y : int) =
(x, y)
let printCell (x, y) =
Printf.printf "Cell -> X(%d) / Y(%d)\n" x y
end
Cell.mli
module type CELL =
sig
type t
val initCell : int -> int -> t
val printCell : t -> unit
end
module Cell : CELL
And here is the Makefile :
NAME = test
ML = Cell.ml \
Laby.ml \
main.ml
MLI = Cell.mli
CMI = $(MLI:.mli=.cmi)
CMO = $(ML:.ml=.cmo)
CMX = $(ML:.ml=.cmx)
OCAMLDPE = ocamldep
CAMLFLAGS = -w Aelz -warn-error A
OCAMLC = ocamlc $(CAMLFLAGS)
OCAMLOPT = ocamlopt $(CAMLFLAGS)
OCAMLDOC = ocamldoc -html -d $(ROOT)/doc
all: .depend $(CMI) $(NAME)
byte: .depend $(CMI) $(NAME).byte
$(NAME): $(CMX)
#$(OCAMLOPT) -o $# $(CMX)
#echo "[OK] $(NAME) linked"
$(NAME).byte: $(CMO)
#$(OCAMLC) -o $# $(CMO)
#echo "[OK] $(NAME).byte linked"
%.cmx: %.ml
#$(OCAMLOPT) -c $<
#echo "[OK] [$<] builded"
%.cmo: %.ml
#$(OCAMLC) -c $<
#echo "[OK] [$<] builded"
%.cmi: %.mli
#$(OCAMLC) -c $<
#echo "[OK] [$<] builded"
documentation: $(CMI)
#$(OCAMLDOC) $(MLI)
#echo "[OK] Documentation"
re: fclean all
clean:
#/bin/rm -f *.cm* *.o .depend *~
#echo "[OK] clean"
fclean: clean
#/bin/rm -f $(NAME) $(NAME).byte
#echo "[OK] fclean"
.depend:
#/bin/rm -f .depend
#$(OCAMLDPE) $(MLI) $(ML) > .depend
#echo "[OK] dependencies"
Here is the output of the Makefile :
[OK] dependencies
[OK] [Cell.mli] builded
[OK] [Cell.ml] builded
File "Laby.ml", line 3, characters 17-30:
Error: Unbound value Cell.initCell
Makefile:47: recipe for target 'Laby.cmx' failed
make: *** [Laby.cmx] Error 2
I think it's a compilation error, since it seems to not found the Cell module, but I can't make it works...
What am I doing wrong, and how can I fix it?
Each .ml file serves as its own module. You seem to have module Cell inside cell.ml which is double. You would have to address that function as Cell.Cell.initCell. Or open Cell in laby.ml. Also, I think .ml file names are conventionally lowercase? Aside: why does make output wrong english?
Related
For a specific requirement, I need my binary to fall below 510bytes.
Doing the program in assembler, I get <100 bytes, while adding same code in C++, the resulting code is over 1K. Looking the resulting binary, mostly all ( + 90%) is full of 0x00 characters (Only a few characters at the beginning and end are really populated).
Currently building commands:
gcc -Wall -Os -s -Wl,--stack,32 -nostdinc -nostdinc++ -fno-ident -fno-builtin -I. -c -o cppFile.coff cppFile.cpp
nasm -f elf -o main.elf main.asm
ld -T link.ld -o out.elf main.elf cppFile.coff
objcopy -O binary out.elf out.bin
Size of files generated:
cppFile.coff = 684 bytes
main.elf = 640
out.elf = 2707
out.bin = 1112
When not linking to the cppFile.coff (with only one empty function)
out.elf = 1984
out.bin = 31 (tested and working)
Why GCC or LD add so many nul charactres?
How to remove this empty space?
ENTRY(start)
phys = 0x7c00;
HEAP_SIZE = 0;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata)
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
}
end = .;
}
So i have the following files:
_oasis:
OASISFormat: 0.4
Name: PongBattleServer
Version: 0.1.0
Synopsis: Server for handling multi-player pong games
Authors: Jason Miesionczek
License: MIT
Plugins: META (0.4), DevFiles (0.4)
Executable pongserver
Path: src
BuildTools: ocamlbuild
MainIs: main.ml
main.ml:
open Players;;
let () =
let mgr = new player_manager
players.ml:
type player =
{
name: string;
score: int;
}
class player_manager =
object (self)
val mutable player_list = ( [] : player list)
method add p =
player_list <- p :: player_list
end;;
when i run make i get this error:
ocaml setup.ml -build
/home/araxia/.opam/system/bin/ocamlfind ocamldep -modules src/main.ml > src/main.ml.depends
+ /home/araxia/.opam/system/bin/ocamlfind ocamldep -modules src/main.ml > src/main.ml.depends
File "src/main.ml", line 4, characters 32-32:
Error: Syntax error
Command exited with code 2.
E: Failure("Command ''/usr/bin/ocamlbuild' src/main.byte -tag debug' terminated with error code 10")
make: *** [build] Error 1
Makefile:7: recipe for target 'build' failed
i am new to ocaml and oasis, etc. what am i doing wrong?
This has nothing to do with Oasis or whatsoever, it's just when you write
let () =
let mgr = new player_manager
OCaml expects an in keyword because either let introduces a global variable either it introduces a local variable and then you'll need a let var = expr in expr, nothing else.
So, replace it by
let () =
let mgr = new player_manager in ()
for now because you aren't doing anything with mgr.
I have a variant type named response that is based on another variant type. But I am unable to use the response variant type as a return value. Here is the code :
type ack_error =
| Not_list
| Arg
| Password
| Permission
| Unknown
| No_exist
| Playlist_max
| System
| Playlist_load
| Update_already
| Player_sync
| Exist
type response = Ok | Error of ack_error * int * string * string
(* some code for the function_parse_error_response which signature is :
* str -> (ack_error * int * string * string)
*)
let parse_response mpd_response =
if mpd_response = "OK\n" then Ok
else parse_error_response mpd_response
I have created a test.ml :
(* ocamlfind ocamlc -o test -package oUnit -linkpkg -g mpd.ml test.ml *)
open OUnit2
let test_ok test_ctxt = assert_equal Ok Mpd.parse_response "OK\n"
let mpd_tests =
"mpd_tests" >:::
["test OK" >:: test_ok]
let () =
run_test_tt_main mpd_tests
And when I try to compile it I have the following error:
ocamlfind ocamlc -o test -package oUnit -linkpkg -g mpd.ml test.ml
File "mpd.ml", line 84, characters 7-40:
Error: This expression has type ack_error * int * string * string
but an expression was expected of type response
parse_error_response mpd_response has type ack_error * int * string * string, not response. You just need to wrap it with the Error constructor:
let parse_response mpd_response =
if mpd_response = "OK\n" then Ok
else Error (parse_error_response mpd_response)
I have written two .f90 text files prog1.f90:
PROGRAM prog1
READ (5,*) A,B,C
PRINT*, "A = ",A
PRINT*, "B = ",B
PRINT*, "C = ",C
CALL test(A,B,C)
END PROGRAM prog1
and aux.f90
SUBROUTINE test(E,F,G)
real(kind=8) :: E,F,G
PRINT*,"E = ",E
PRINT*,"F = ",F
PRINT*,"G = ",G
END SUBROUTINE test
Which are compiled using the Makefile:
FC = gfortran
FCFLAGS = -g -fbounds-check
FCFLAGS = -O2
FCFLAGS += -I/usr/include
PROGRAMS = prog1
all: $(PROGRAMS)
prog1: aux.o
%: %.o
$(FC) $(FCFLAGS) -o $# $^ $(LDFLAGS)
%.o: %.f90
$(FC) $(FCFLAGS) -c $<
%.o: %.F90
$(FC) $(FCFLAGS) -c $<
.PHONY: clean veryclean
clean:
rm -f *.o *.mod *.MOD
veryclean: clean
rm -f *~ $(PROGRAMS)
I use this makefile to compile prog1 and then run prog1 with the input file input.inp:
0.0033943878 0.0018085515 0.0011798956
I expect the output of this code to be
A = 0.339439E-02
B = 0.180855E-02
C = 0.117990E-02
E = 0.339439E-02
F = 0.180855E-02
G = 0.117990E-02
However it is:
A = 0.339439E-02
B = 0.180855E-02
C = 0.117990E-02
E = 0.100765847236215E-21
F = 0.750936901926887E-24
G = 0.261410786221168-313
The number are much much smaller in the subroutine and seem to have no logical connection to the original A,B and C and are returned from the subroutine as such.
I take it my error is to do with the type I am storing these numbers as, i.e. they are not read in as real(kind=8) but are being converted into this type causing the error but I am not sure what the type should be in the subroutine or if this is even the cause. I may just be missing something obvious.
Any help would be appreciated and please tell me if I need to clarify anything I have written.
Thank you for your time.
James
You made the common error to forget the IMPLICIT NONE statement at the beginning of your program. (At least, it is heavily recommended to avoid this kind of error.)
As a result, all variables starting with I, J, K, L, M or N are of type INTEGER(4) and all other variables of type REAL(4). This means, that your variables A, B and C are of REAL(4). Passing them to the subroutine results in principle in an undetected type mismatch which results in misinterpreted values.
You should always place IMPLICIT NONE at the beginning of your programs and modules to be forced to specify explicit types for your variables!
I think I have fixed this error by correcting prog1.f90:
PROGRAM prog1
real(kind=8) :: A,B,C
READ (5,*) A,B,C
PRINT*, "A = ",A
PRINT*, "B = ",B
PRINT*, "C = ",C
CALL test(A,B,C)
END PROGRAM prog1
I am a student in ECE working on a programming assignment; it has already been submitted and is being graded, but I still want to know why my makefile isn't working. When I run the file on our school server with the command 'make tests' it responds
'make: testq: command not found.
make * tests error 127
If I run 'make testq12345' it will actually run my program "myar" and produce the output file, but it will then give an error 255. I don't understand the issue, or why the makefile cannot find the targets. I've searched via stackoverflow and other sources about these errors but don't understand and can't find a workable solution. If it matters I'm running it on a Linux server.
I am running it in CS311/Homework4/test which contains the makefile, programs and text files.
Thanks for your time and assistance; its appreciated.
#
# $RCSfile$
# $Revision$
# $Author$
# $Date$
# $Log$
#
# Author: Cody R Crawford
# Email: crawfoco#onid.orst.edu
# Course: CS311-400
# Homework: 4
# Citations:
# http://mrbook.org/tutorials/make/
# For examples, guidance, and genera understanding
# Assumptions: I assume you want the .o files to show up unless
# you specifically command 'clean'
#########################################################
CC=gcc
DEBUG=-g
CFLAGS=$(DEBUG) -Wall
PROGS=sig_demo myar
OBJECTS=$(PROGS:.c=.o)
all: $(PROGS)
sig_demo.o: sig_demo.c
$(CC) $(CFLAGS) -c sig_demo.c
sig_demo.c: sig_demo.o
$(CC) $(CFLAGS) -c sig_demo.c
myar.o: myar.c
$(CC) $(CFLAGS) -c myar.c
myar.c: myar.o
$(CC) $(CFLAGS) -c myar.c
tests:
testq
testt
testv
testq:
testq24
testq135
testq12345
testq24:
rm -f ar24.ar
ar q ar24.ar 2-s.txt 4-s.txt
myar q myar24.ar 2-s.txt 4-s.txt
diff ar24.ar myar24.ar
testq135:
rm -f ar135.ar
ar q ar135.ar 1-s.txt 3-s.txt 5-s.txt
myar q myar135.ar 1-s.txt 3-s.txt 5-s.txt
diff ar135.ar myar135.ar
testq12345:
rm -f ar12345.ar
rm -f myar12345.ar
ar q ar12345.ar 1-s.txt 2-s.txt 3-s.txt 4-s.txt 5-s.txt
./myar -q myar12345.ar 1-s.txt 2-s.txt 3-s.txt 4-s.txt 5-s.txt
diff ar135.ar myar135.ar
testt:
testt24
testt135
testt12345
testt24:
rm -f ar24.ar
ar q ar24.ar 2-s.txt 4-s.txt
ar t ar24.ar > ar-ctoc.txt
myar -t ar24.ar > myar-ctoc.txt
diff ar-ctoc.txt myar-ctoc.txt
testt135:
rm -f ar135.ar
ar q ar135.ar 1-s.txt 3-s.txt 5-s.txt
ar t ar135.ar > ar-ctoc.txt
myar -t ar135.ar > myar-ctoc.txt
diff ar-ctoc.txt myar-ctoc.txt
testt12345:
rm -f ar12345.ar
ar q ar12345.ar 1-s.txt 2-s.txt 3-s.txt 4-s.txt 5-s.txt
ar t ar12345.ar > ar-ctoc.txt
myar -t ar12345.ar > myar-ctoc.txt
diff ar-ctoc.txt myar-ctoc.txt
testv:
testv24
testv135
testv12345
testv24:
rm -f ar24.ar
ar q ar24.ar 2-s.txt 4-s.txt
ar v ar24.ar > ar-ctoc.txt
myar -v ar24.ar > myar-ctoc.txt
diff ar-ctoc.txt myar-ctoc.txt
testv135:
rm -f ar135.ar
ar q ar135.ar 1-s.txt 3-s.txt 5-s.txt
ar v ar135.ar > ar-ctoc.txt
myar -v ar135.ar > myar-ctoc.txt
diff ar-ctoc.txt myar-ctoc.txt
testv12345:
rm -f ar12345.ar
ar q ar12345.ar 1-s.txt 2-s.txt 3-s.txt 4-s.txt 5-s.txt
ar v ar12345.ar > ar-ctoc.txt
myar -v ar12345.ar > myar-ctoc.txt
diff ar-ctoc.txt myar-ctoc.txt
clean:
rm -f $(PROGS) $(OBJECTS) *.o *~
Dependencies should be listed on the same line, otherwise it will try to execute them as commands;
For example;
tests:
testq
testt
testv
will just try to execute the shell commands testq, testt and testv which don't exist and give your error, while;
tests: testq testt testv
will just see to that the makefile targets testq, testt and testv are completed before the target tests is executed. In this case tests contains no commands, so the only thing that target does is see to that the depdendencies are executed.
I think you are looking for this:
A simple makefile consists of "rules" with the following shape:
target ... : dependencies ...
command
...
...
This is what you need to fix:
tests: testq testt testv
testq: testq24 testq135 testq12345
testv: testv24 testv135 testv12345