X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fparser.mly;h=c6f961d2e42285e3add102ed9bc12b0d0c060840;hb=7b7cd85810f18286a36215cc164b659bf7db142c;hp=c47ac597f3b818682ed0028da63aaff20c19d557;hpb=24cc20b33e3d81ed7d754391bef929276c1f4f42;p=goals.git diff --git a/src/parser.mly b/src/parser.mly index c47ac59..c6f961d 100644 --- a/src/parser.mly +++ b/src/parser.mly @@ -18,7 +18,14 @@ *) %{ +open Utils open Printf + +(* This is initialized with Lexer.read once the program + * starts. Doing this avoids a circular dependency caused + * by include files. + *) +let lexer_read = ref None %} (* Tokens. *) @@ -29,6 +36,7 @@ open Printf %token EOF %token GOAL %token ID +%token INCLUDE %token LEFT_ARRAY %token LEFT_PAREN %token LET @@ -36,9 +44,10 @@ open Printf %token RIGHT_PAREN %token STRING %token TACTIC +%token TACTIC_KEYWORD (* Start nonterminals. *) -%start file +%start file %start expr %% @@ -47,12 +56,35 @@ file: ; stmts: - | list(stmt) - { List.fold_left ( - fun env (name, expr) -> Ast.Env.add name expr env - ) Ast.Env.empty $1 + | (* none *) { Ast.Env.empty } + | stmts INCLUDE STRING + { + let env = $1 in + let filename = Ast.substitute env $loc $3 in + let rec find_on_include_path = + function + | [] -> filename + | inc :: incs -> + let path = inc // filename in + if Sys.file_exists path then path + else find_on_include_path incs + in + let filename = + if Filename.is_implicit filename then + find_on_include_path Cmdline.includes + else filename in + let fp = open_in filename in + let lexbuf = Lexing.from_channel fp in + lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = filename }; + let reader = + match !lexer_read with None -> assert false | Some r -> r in + let env' = file reader lexbuf in + close_in fp; + Ast.Env.merge env env' } + | stmts stmt { let name, expr = $2 in Ast.Env.add name expr $1 } ; + stmt: | option(goal_stmt) patterns COLON barelist option(CODE) { let name, params = @@ -67,6 +99,10 @@ stmt: let name, params = $1 in name, Ast.EGoal ($loc, (params, [], [], Some $2)) } + | TACTIC_KEYWORD TACTIC params_decl EQUALS CODE + { + $2, Ast.ETactic ($loc, ($3, $5)) + } | LET ID EQUALS expr { $2, $4 } ; @@ -84,9 +120,8 @@ patterns: | separated_list(COMMA, pattern) { $1 } ; pattern: - | STRING { Ast.PTactic ($loc, "file", [$1]) } + | STRING { Ast.PTactic ($loc, "*file", [$1]) } | ID pattern_params { Ast.PTactic ($loc, $1, $2) } - | ID { Ast.PVar ($loc, $1) } ; pattern_params: | LEFT_PAREN separated_list(COMMA, pattern_param) RIGHT_PAREN { $2 } @@ -96,9 +131,9 @@ pattern_param: ; expr: - | ID params { Ast.ECall ($loc, $1, $2) } + | ID params { Ast.ECallGoal ($loc, $1, $2) } | ID { Ast.EVar ($loc, $1) } - | TACTIC params { Ast.ETactic ($loc, $1, $2) } + | TACTIC params { Ast.ECallTactic ($loc, $1, $2) } | STRING { Ast.ESubsts ($loc, $1) } | LEFT_ARRAY barelist RIGHT_ARRAY { Ast.EList ($loc, $2) } ;