mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 18:40:16 +01:00
Add line editor to RE2 example. (#6337)
Most inputs are matched against the current regex. An input that starts and ends with `/` sets a new regex instead. EOF terminates the program. --------- Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
This commit is contained in:
@@ -19,7 +19,7 @@ def _carbon_binary_impl(ctx):
|
||||
# Pass any C++ flags from our dependencies onto Carbon.
|
||||
dep_flags = []
|
||||
dep_hdrs = []
|
||||
dep_link_flags = []
|
||||
dep_link_flags = ["-lc++"]
|
||||
dep_link_inputs = []
|
||||
for dep in ctx.attr.deps:
|
||||
if CcInfo in dep:
|
||||
@@ -75,7 +75,8 @@ def _carbon_binary_impl(ctx):
|
||||
inputs = depset(direct = srcs_reordered, transitive = dep_hdrs),
|
||||
executable = toolchain_driver,
|
||||
tools = depset(toolchain_data),
|
||||
arguments = ["compile", "--output=" + out.path, "--clang-arg=-stdlib=libc++"] + [s.path for s in srcs_reordered] + extra_flags,
|
||||
arguments = ["compile", "--output=" + out.path, "--clang-arg=-stdlib=libc++"] +
|
||||
[s.path for s in srcs_reordered] + extra_flags + ctx.attr.flags,
|
||||
mnemonic = "CarbonCompile",
|
||||
progress_message = "Compiling " + src.short_path,
|
||||
)
|
||||
@@ -86,7 +87,7 @@ def _carbon_binary_impl(ctx):
|
||||
inputs = objs + dep_link_inputs,
|
||||
executable = toolchain_driver,
|
||||
tools = depset(toolchain_data),
|
||||
arguments = ["link", "--output=" + bin.path] + dep_link_flags + [o.path for o in objs],
|
||||
arguments = ["link", "--output=" + bin.path] + ["--"] + dep_link_flags + [o.path for o in objs],
|
||||
mnemonic = "CarbonLink",
|
||||
progress_message = "Linking " + bin.short_path,
|
||||
)
|
||||
@@ -96,6 +97,7 @@ _carbon_binary_internal = rule(
|
||||
implementation = _carbon_binary_impl,
|
||||
attrs = {
|
||||
"deps": attr.label_list(allow_files = True, providers = [[CcInfo]]),
|
||||
"flags": attr.string_list(),
|
||||
# The exec config toolchain driver and data. These will be `None` when
|
||||
# using the target config and populated when using the exec config. We
|
||||
# have to use duplicate attributes here and below to have different
|
||||
@@ -130,13 +132,14 @@ _carbon_binary_internal = rule(
|
||||
executable = True,
|
||||
)
|
||||
|
||||
def carbon_binary(name, srcs, deps = [], tags = []):
|
||||
def carbon_binary(name, srcs, deps = [], flags = [], tags = []):
|
||||
"""Compiles a Carbon binary.
|
||||
|
||||
Args:
|
||||
name: The name of the build target.
|
||||
srcs: List of Carbon source files to compile.
|
||||
deps: List of dependencies.
|
||||
flags: Extra flags to pass to the Carbon compile command.
|
||||
tags: Tags to apply to the rule.
|
||||
"""
|
||||
_carbon_binary_internal(
|
||||
@@ -144,6 +147,7 @@ def carbon_binary(name, srcs, deps = [], tags = []):
|
||||
srcs = srcs,
|
||||
prelude_srcs = ["//core:prelude_files"],
|
||||
deps = deps,
|
||||
flags = flags,
|
||||
tags = tags,
|
||||
|
||||
# We synthesize two sets of attributes from mirrored `select`s here
|
||||
|
||||
@@ -7,6 +7,10 @@ load("//bazel/carbon_rules:defs.bzl", "carbon_binary")
|
||||
carbon_binary(
|
||||
name = "re2_playground",
|
||||
srcs = ["re2_playground.carbon"],
|
||||
flags = ["--clang-arg=-std=c++20"],
|
||||
tags = ["manual"],
|
||||
deps = ["@re2"],
|
||||
deps = [
|
||||
"@llvm-project//llvm:LineEditor",
|
||||
"@re2",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -2,41 +2,60 @@
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
import Cpp library "llvm/LineEditor/LineEditor.h";
|
||||
import Cpp library "llvm/Support/raw_ostream.h";
|
||||
import Cpp library "re2/re2.h";
|
||||
|
||||
import Cpp inline '''c++
|
||||
// A wrapper around RE2 working around lack of:
|
||||
//
|
||||
// * Overloading support for the constructor.
|
||||
// * Non-null pointer support for the `submatch` parameter.
|
||||
struct WrapRE2 : re2::RE2 {
|
||||
WrapRE2(std::string_view v) : RE2(v) {}
|
||||
bool Match(absl::string_view text, size_t startpos, size_t endpos,
|
||||
Anchor re_anchor, absl::string_view* _Nonnull submatch,
|
||||
int nsubmatch) const {
|
||||
return RE2::Match(text, startpos, endpos, re_anchor, submatch, nsubmatch);
|
||||
}
|
||||
};
|
||||
''';
|
||||
import Cpp inline "using OptionalString = std::optional<std::string>;";
|
||||
import Cpp inline "std::string_view AsStringView(const std::string &s) { return s; }";
|
||||
|
||||
import Core library "io";
|
||||
|
||||
class RE2 {
|
||||
extend adapt Cpp.WrapRE2;
|
||||
extend adapt Cpp.re2.RE2;
|
||||
fn Make(re: str) -> Self {
|
||||
return WrapRE2(re) as Self;
|
||||
return RE2(re) as Self;
|
||||
}
|
||||
fn Match[self: Self](text: str) -> bool {
|
||||
var submatches: str;
|
||||
return (self as Cpp.WrapRE2).Match(text, 0, text.Size(), UNANCHORED, &submatches, 0);
|
||||
return FullMatch(text, self as Cpp.re2.RE2);
|
||||
}
|
||||
}
|
||||
|
||||
impl str as Core.ImplicitAs(Cpp.llvm.StringRef) {
|
||||
fn Convert[self: Self]() -> Cpp.llvm.StringRef {
|
||||
return Cpp.llvm.StringRef.StringRef(self);
|
||||
}
|
||||
}
|
||||
|
||||
fn Print(var s: str) {
|
||||
*Cpp.llvm.outs() << s;
|
||||
}
|
||||
|
||||
fn Run() -> i32 {
|
||||
var editor: Cpp.llvm.LineEditor = Cpp.llvm.LineEditor.LineEditor("re2_playground");
|
||||
editor.setPrompt(Cpp.std.string.basic_string("re2> "));
|
||||
|
||||
Print('''
|
||||
Usage:
|
||||
/regex/ -- sets the current regular expression to regex
|
||||
anything else -- matches the entered text against the specified regex
|
||||
''');
|
||||
|
||||
var re: RE2 = RE2.Make("^a*$");
|
||||
if (re.Match("aaaaaaaab")) {
|
||||
return 1;
|
||||
}
|
||||
if (not re.Match("aaaaaaaaa")) {
|
||||
return 1;
|
||||
while (true) {
|
||||
var line: Cpp.OptionalString = editor.readLine();
|
||||
if (not line.has_value()) {
|
||||
break;
|
||||
}
|
||||
if (line.value()->starts_with("/") and line.value()->ends_with("/")) {
|
||||
re = RE2.Make(Cpp.AsStringView(line.value()->substr(1, line.value()->size() - 2)));
|
||||
continue;
|
||||
}
|
||||
if (re.Match(Cpp.AsStringView(*line.value()))) {
|
||||
Print("Match\n");
|
||||
} else {
|
||||
Print("No match\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user