Skip to content
This repository was archived by the owner on Aug 19, 2022. It is now read-only.

Commit 65197ce

Browse files
committed
Initial commit
0 parents  commit 65197ce

File tree

7 files changed

+1105
-0
lines changed

7 files changed

+1105
-0
lines changed

COPYING

+674
Large diffs are not rendered by default.

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
all:
2+
ocamlbuild -use-menhir -tag thread -use-ocamlfind -quiet -pkg core main.native

lexer.mll

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
(*
2+
Copyright 2016 Emmanouil Pitsidianakis
3+
4+
This file is part of ocaml-prolog.
5+
6+
ocaml-prolog is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
ocaml-prolog is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with ocaml-prolog. If not, see <http://www.gnu.org/licenses/>.
18+
*)
19+
{
20+
open Lexing
21+
open Parser
22+
23+
exception SyntaxError of string
24+
25+
let next_line lexbuf =
26+
let pos = lexbuf.lex_curr_p in
27+
lexbuf.lex_curr_p <-
28+
{ pos with pos_bol = pos.pos_cnum;
29+
pos_lnum = pos.pos_lnum + 1;
30+
}
31+
}
32+
33+
let whitespace = [ ' ' '\t']+
34+
let newline = '\r' | '\n' | "\r\n"
35+
let constant = ['a' - 'z' '_'] ['a'-'z' 'A'-'Z' '0'-'9' '_']*
36+
let variable = ['A'-'Z'] ['a'-'z' 'A'-'Z' '0'-'9' '_']*
37+
38+
rule token = parse
39+
| whitespace { token lexbuf }
40+
| newline { next_line lexbuf ; token lexbuf }
41+
| variable as v { VAR v }
42+
| constant as v { CONST v }
43+
| '(' { LPAREN }
44+
| ')' { RPAREN }
45+
| ':' { COLON }
46+
| '-' { DASH }
47+
| '.' { PERIOD }
48+
| ',' { COMMA }
49+
| '[' { LBRACKET }
50+
| ']' { RBRACKET }
51+
| '\'' { APOSTROPHE }
52+
| eof { EOF }
53+
| _ { raise (SyntaxError ("Unexpected char: " ^ Lexing.lexeme lexbuf)) }

main.ml

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
(*
2+
Copyright 2016 Emmanouil Pitsidianakis
3+
4+
This file is part of ocaml-prolog.
5+
6+
ocaml-prolog is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
ocaml-prolog is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with ocaml-prolog. If not, see <http://www.gnu.org/licenses/>.
18+
*)
19+
open Core.Std
20+
open Lexer
21+
open Lexing
22+
open Prolog
23+
open Print
24+
25+
let print_position outx lexbuf =
26+
let pos = lexbuf.lex_curr_p in
27+
fprintf outx "%s:%d:%d" pos.pos_fname
28+
pos.pos_lnum (pos.pos_cnum - pos.pos_bol + 1)
29+
30+
let parse lexbuf =
31+
try Parser.main Lexer.token lexbuf with
32+
| SyntaxError msg ->
33+
print_string msg ; []
34+
| Parser.Error ->
35+
fprintf stdout "%a: syntax error\n" print_position lexbuf; []
36+
37+
(*
38+
let rec print_parsed l =
39+
let rec loop x =
40+
match x with
41+
| [] -> ()
42+
| (Compound hd)::tl -> Syntax.print_compound hd ; loop tl
43+
| (Load f)::_ -> parse_file f; ()
44+
| _ -> halt ()
45+
in
46+
loop l*)
47+
let parse_file filename =
48+
let fullname = (String.concat ~sep:"" [filename;".pl"]) in
49+
let inx = In_channel.create fullname in
50+
let lexbuf = Lexing.from_channel inx in
51+
lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = filename }; parse lexbuf |> Prolog.assert_f ; Print.color_print (Basic (Red,Bold)) [fullname; " compiled"] ;
52+
In_channel.close inx
53+
and parse_cmd cmd =
54+
let lexbuf = Lexing.from_string cmd in
55+
lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = cmd };
56+
parse lexbuf
57+
58+
(* standard predicates *)
59+
let assertf = function
60+
[f] -> parse_file f
61+
| _ -> assert false
62+
63+
let halt = fun () -> (print_endline "Halt." ; exit 0)
64+
65+
let exec_std_function (Op (x,y)) =
66+
let rec extract_vals acc = function
67+
| [] -> List.rev acc
68+
| (Const x)::xs | (Var x)::xs -> extract_vals (x::acc) xs
69+
| _ -> assert false
70+
in match x with
71+
| "print" -> Prolog.print_database () ; true
72+
| "halt" -> halt ()
73+
| "assert" -> assertf (extract_vals [] y) ; true
74+
| _ -> false
75+
76+
let solve cmd =
77+
match parse_cmd cmd with
78+
| ({ head = q ; body = [] })::_ -> (match exec_std_function q with
79+
| true -> ()
80+
| false -> Prolog.solve_prompt q)
81+
| _ -> ()
82+
83+
let prompt () =
84+
try
85+
while true do
86+
print_string "?- ";
87+
let cmd = read_line () in
88+
begin
89+
try solve cmd
90+
with Match_failure (x,y,z) -> print_endline ("Match_failure, not a valid command " ^ x ^ ":" ^ (string_of_int y)^":"^(string_of_int z))
91+
end
92+
done
93+
with End_of_file -> halt ()
94+
95+
let () =
96+
prompt ()
97+
(*let () =
98+
Command.basic ~summary:"Parse Prolog"
99+
~readme:(fun () -> "More detailed information")
100+
Command.Spec.(
101+
empty
102+
+> flag "-f" (optional file) ~doc:"file Parse the file"
103+
)
104+
(fun file () -> match file with
105+
| Some f -> parse f ; prompt
106+
| None -> prompt
107+
)
108+
109+
|> Command.run*)

parser.mly

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
(*
2+
Copyright 2016 Emmanouil Pitsidianakis
3+
4+
This file is part of ocaml-prolog.
5+
6+
ocaml-prolog is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
ocaml-prolog is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with ocaml-prolog. If not, see <http://www.gnu.org/licenses/>.
18+
*)
19+
%{
20+
open Prolog
21+
%}
22+
23+
%token <string> CONST
24+
%token <string> VAR
25+
%token COMMA
26+
%token COLON
27+
%token PERIOD
28+
%token LPAREN
29+
%token RPAREN
30+
%token LBRACKET
31+
%token RBRACKET
32+
%token EOF
33+
%token DASH
34+
%token APOSTROPHE
35+
36+
%start main
37+
%type <Prolog.clause list> main
38+
39+
%%
40+
41+
main:
42+
| EOF { [] }
43+
| clause { $1 }
44+
45+
clause:
46+
| rule main { $1 :: $2 }
47+
48+
rule:
49+
| LBRACKET v = VAR RBRACKET PERIOD
50+
| LBRACKET v = CONST RBRACKET PERIOD { { head = (Op ("assert",[(Var v)])); body=[] } }
51+
| CONST PERIOD { { head=(Op ($1,[])); body=[] } }
52+
| CONST LPAREN arguments RPAREN PERIOD { { head = (Op ($1,$3)); body = [] } }
53+
| CONST LPAREN arguments RPAREN COLON DASH goals PERIOD { { head=(Op ($1,$3)) ; body= $7 } }
54+
55+
goals:
56+
| goal { [$1] }
57+
| goal COMMA goals { $1 :: $3 }
58+
59+
goal:
60+
| CONST LPAREN arguments RPAREN { Op ($1,$3) }
61+
62+
arguments:
63+
| term { [$1] }
64+
| term COMMA arguments { $1 :: $3 }
65+
66+
term:
67+
| APOSTROPHE CONST APOSTROPHE { Const $2 }
68+
| CONST { Const $1 }
69+
| VAR { Var $1 }
70+
| goal { $1 }
71+
%%

print.ml

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
(*
2+
Copyright 2016 Emmanouil Pitsidianakis
3+
4+
This file is part of ocaml-prolog.
5+
6+
ocaml-prolog is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
ocaml-prolog is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with ocaml-prolog. If not, see <http://www.gnu.org/licenses/>.
18+
*)
19+
open Core.Std
20+
21+
(* terminal colours *)
22+
23+
type basic_color =
24+
| Black | Red | Green | Yellow | Blue | Magenta | Cyan | White
25+
26+
let basic_color_to_int = function
27+
| Black -> 0 | Red -> 1 | Green -> 2 | Yellow -> 3 | Blue -> 4 | Magenta -> 5 | Cyan -> 6 | White -> 7
28+
29+
type weight = Regular | Bold
30+
31+
type color =
32+
| Basic of basic_color * weight (* basic colors, regular and bold *)
33+
| RGB of int * int * int (* 6x6x6 color cube *)
34+
| Gray of int (* 24 grayscale levels *)
35+
36+
let color_by_number number text = sprintf "\027[38;5;%dm%s\027[0m" number text;;
37+
38+
let color_to_int = function
39+
| Basic (basic_color,weight) ->
40+
let base = match weight with Bold -> 8 | Regular -> 0 in
41+
base + basic_color_to_int basic_color
42+
| RGB (r,g,b) -> 16 + b + g * 6 + r * 36
43+
| Gray i -> 232 + i
44+
45+
let rec color_print color s = match s with
46+
| [] -> printf "\n"
47+
| x::xs -> printf "%s" (color_by_number (color_to_int color) x) ; color_print color xs
48+
49+

0 commit comments

Comments
 (0)