Skip to content

Commit

Permalink
Add bitmaps support (OCaml backend).
Browse files Browse the repository at this point in the history
  • Loading branch information
skvadrik committed Sep 20, 2024
1 parent 5a4afb1 commit eac735f
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 23 deletions.
18 changes: 12 additions & 6 deletions bootstrap/src/default_syntax_ocaml.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const char* DEFAULT_SYNTAX_OCAML =
"supported_api_styles = [\"free-form\"];\n"
"supported_code_models = [\"recursive-functions\"];\n"
"supported_targets = [\"code\", \"dot\"];\n"
"supported_features = [\"nested-ifs\", \"case-ranges\", \"tags\", \"captures\", \"captvars\"];\n"
"supported_features = [\"nested-ifs\", \"bitmaps\", \"case-ranges\",\n"
" \"tags\", \"captures\", \"captvars\"];\n"
"\n"
"\n"
"// language-specific options ---------------------------------------------------\n"
Expand Down Expand Up @@ -159,14 +160,19 @@ const char* DEFAULT_SYNTAX_OCAML =
"code:const_local = topindent \"let \" name \" = \" init \" in\" nl;\n"
"code:const_global = topindent \"let \" name \" = \" init nl;\n"
"\n"
"code:array_local = <undefined>;\n"
"code:array_global = <undefined>;\n"
"code:array_local =\n"
" topindent \"and \" name \" = [|\" nl indent\n"
" [row: topindent [elem{0:-2}: elem \"; \"] [elem{-1}: elem \";\"] nl]\n"
" dedent topindent \"|]\" nl;\n"
"\n"
"code:array_global = code:array_local;\n"
"\n"
"code:array_elem = array \".(\" index \")\";\n"
"\n"
"code:type_int = \"int\";\n"
"code:type_uint = \"uint\";\n"
"code:type_cond_enum = (storable_state? \"int\" : \"uint\");\n"
"code:type_yybm = <undefined>;\n"
"code:type_yybm = \"int\";\n"
"code:type_yytarget = <undefined>;\n"
"\n"
"code:assign = topindent lhs \" <- \" rhs \";\" nl;\n"
Expand Down Expand Up @@ -384,7 +390,7 @@ const char* DEFAULT_SYNTAX_OCAML =
" : YYLIMIT \" <= \" YYCURSOR)\n"
" : YYLESSTHAN);\n"
"\n"
"code:yybm_filter = <undefined>;\n"
"code:yybm_filter = yych \" land ~0xFF\";\n"
"\n"
"code:yybm_match = <undefined>;\n"
"code:yybm_match = \"(\" yybm \".(\" offset \" + Char.code \" yych \") land \" mask \") != 0\";\n"
;
18 changes: 12 additions & 6 deletions include/syntax/ocaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ supported_apis = ["record", "generic"];
supported_api_styles = ["free-form"];
supported_code_models = ["recursive-functions"];
supported_targets = ["code", "dot"];
supported_features = ["nested-ifs", "case-ranges", "tags", "captures", "captvars"];
supported_features = ["nested-ifs", "bitmaps", "case-ranges",
"tags", "captures", "captvars"];


// language-specific options ---------------------------------------------------
Expand Down Expand Up @@ -157,14 +158,19 @@ code:var_global = topindent "let " name " = " init nl;
code:const_local = topindent "let " name " = " init " in" nl;
code:const_global = topindent "let " name " = " init nl;

code:array_local = <undefined>;
code:array_global = <undefined>;
code:array_local =
topindent "and " name " = [|" nl indent
[row: topindent [elem{0:-2}: elem "; "] [elem{-1}: elem ";"] nl]
dedent topindent "|]" nl;

code:array_global = code:array_local;

code:array_elem = array ".(" index ")";

code:type_int = "int";
code:type_uint = "uint";
code:type_cond_enum = (storable_state? "int" : "uint");
code:type_yybm = <undefined>;
code:type_yybm = "int";
code:type_yytarget = <undefined>;

code:assign = topindent lhs " <- " rhs ";" nl;
Expand Down Expand Up @@ -382,6 +388,6 @@ code:yylessthan =
: YYLIMIT " <= " YYCURSOR)
: YYLESSTHAN);

code:yybm_filter = <undefined>;
code:yybm_filter = yych " land ~0xFF";

code:yybm_match = <undefined>;
code:yybm_match = "(" yybm ".(" offset " + Char.code " yych ") land " mask ") != 0";
14 changes: 9 additions & 5 deletions src/codegen/pass2_generate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1724,18 +1724,20 @@ CodeList* gen_bitmap(Output& output, const CodeBitmap* bitmap, const std::string
return stmts;
}

static void gen_bitmaps(Output& output, CodeList* code, bool* local_decls) {
static bool gen_bitmaps(Output& output, CodeList* code) {
OutputBlock& b = output.block();

if (!b.opts->bitmaps) return;
if (!b.opts->bitmaps) return false;

bool have_bitmaps = false;
for (const std::unique_ptr<Adfa>& dfa : b.dfas) {
CodeList* bitmap = gen_bitmap(output, dfa->bitmap, dfa->cond);
if (bitmap) {
*local_decls = true;
have_bitmaps = true;
append(code, bitmap);
}
}
return have_bitmaps;
}

void gen_dfa_as_blocks_with_labels(Output& output, const Adfa& dfa, CodeList* stmts) {
Expand Down Expand Up @@ -1930,7 +1932,7 @@ LOCAL_NODISCARD(Ret gen_block_code(Output& output, const Adfas& dfas, CodeList*
append(code, gen_cond_table(output));
}

gen_bitmaps(output, code, &local_decls);
local_decls |= gen_bitmaps(output, code);

if (opts->storable_state) {
CHECK_RET(gen_state_goto_implicit(output, code));
Expand Down Expand Up @@ -1968,7 +1970,7 @@ LOCAL_NODISCARD(Ret gen_block_code(Output& output, const Adfas& dfas, CodeList*
local_decls = true;
append(code, gen_yystate_def(output));

gen_bitmaps(output, code, &local_decls);
local_decls |= gen_bitmaps(output, code);

CodeCases* cases = code_cases(alc);
for (const std::unique_ptr<Adfa>& dfa : dfas) {
Expand All @@ -1989,6 +1991,8 @@ LOCAL_NODISCARD(Ret gen_block_code(Output& output, const Adfas& dfas, CodeList*
CHECK_RET(gen_start_function(output, *dfas[0], funcs));

append(code, code_recursive_functions(alc, funcs));

gen_bitmaps(output, code); // no local declarations in rec/func mode => ignore return value
}

// If needed, wrap the block in braces, so that variable declarations have local scope.
Expand Down
4 changes: 0 additions & 4 deletions src/options/opt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,6 @@ LOCAL_NODISCARD(Ret fix_mutopt(
RET_FAIL(error("computed gotos are not supported in this code model"));
}
}
if (real.bitmaps && glob.code_model == CodeModel::REC_FUNC) {
// TODO: allow bitmaps before in rec/func mode
RET_FAIL(error("bitmaps are not supported in this code model"));
}

return Ret::OK;
}
Expand Down
82 changes: 82 additions & 0 deletions test/codegen/ocaml/01_basic_b.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
(* Generated by re2ocaml *)
#1 "codegen/ocaml/01_basic_b.re"
(* re2ocaml $INPUT -o $OUTPUT -b *)

type state = {
str: string;
mutable cur: int;
}


#12 "codegen/ocaml/01_basic_b.ml"
let rec yy0 (st : state) : bool =
let yych = st.str.[st.cur] in
st.cur <- st.cur + 1;
if (yych <= '0') then (yy1 [@tailcall]) st
else if (yych <= '9') then (yy2 [@tailcall]) st
else (yy1 [@tailcall]) st

and yy1 (st : state) : bool =
#18 "codegen/ocaml/01_basic_b.re"
false
#23 "codegen/ocaml/01_basic_b.ml"

and yy2 (st : state) : bool =
let yych = st.str.[st.cur] in
if ((yybm.(0 + Char.code yych) land 128) != 0) then (
st.cur <- st.cur + 1;
(yy2 [@tailcall]) st
) else (
(yy3 [@tailcall]) st
)

and yy3 (st : state) : bool =
#17 "codegen/ocaml/01_basic_b.re"
true
#37 "codegen/ocaml/01_basic_b.ml"

and lex (st : state) : bool =
(yy0 [@tailcall]) st

and yybm = [|
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
128; 128; 128; 128; 128; 128; 128; 128;
128; 128; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
0; 0; 0; 0; 0; 0; 0; 0;
|]
#19 "codegen/ocaml/01_basic_b.re"


let main () =
let st = {str = "1234\x00"; cur = 0}
in if not (lex st) then raise (Failure "error")

let _ = main ()
25 changes: 25 additions & 0 deletions test/codegen/ocaml/01_basic_b.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(* re2ocaml $INPUT -o $OUTPUT -b *)

type state = {
str: string;
mutable cur: int;
}

/*!re2c
re2c:api = custom;
re2c:define:YYFN = ["lex;bool", "st;state"];
re2c:define:YYPEEK = "st.str.[st.cur]";
re2c:define:YYSKIP = "st.cur <- st.cur + 1;";
re2c:yyfill:enable = 0;
number = [1-9][0-9]*;
number { true }
* { false }
*/

let main () =
let st = {str = "1234\x00"; cur = 0}
in if not (lex st) then raise (Failure "error")

let _ = main ()
1 change: 0 additions & 1 deletion test/codegen/ocaml/unsupported_bitmaps.ml

This file was deleted.

1 change: 0 additions & 1 deletion test/codegen/ocaml/unsupported_bitmaps.re

This file was deleted.

0 comments on commit eac735f

Please sign in to comment.