Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
compiler_line_frontend_test.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
36#include <gtest/gtest.h>
37
40
41using namespace Aleph;
42
43namespace
44{
47 {
49 inputs.append({"math.line",
50 "func add x y = add x y\n"});
51 inputs.append({"main.line",
52 "import math.line\n"
53 "let answer = call add 40 2\n"});
54 return inputs;
55 }
56}
57
59{
62
63 ASSERT_TRUE(driver.execute_sources(make_line_inputs(), Compiler_Driver_Action::Run));
64 ASSERT_TRUE(driver.run_output().executed);
65 ASSERT_TRUE(driver.run_output().result.ok());
66 EXPECT_EQ(driver.run_output().globals_text,
67 "Globals\n"
68 " add = Function(add)\n"
69 " answer = Int(42)\n");
70
71 const auto * parse_artifact = frontend.find_artifact("line.parse");
72 ASSERT_NE(parse_artifact, nullptr);
73 EXPECT_NE(parse_artifact->text.find("LineProgram"), std::string::npos);
74
75 const auto * order_artifact = frontend.find_artifact("imports.order");
76 ASSERT_NE(order_artifact, nullptr);
78 "ImportOrder\n"
79 " [0] math.line\n"
80 " [1] main.line\n");
81 const auto * surface = driver.find_artifact("modules.surface");
82 ASSERT_NE(surface, nullptr);
83 EXPECT_NE(surface->text.find("Module(math.line)"), std::string::npos);
84 EXPECT_NE(surface->text.find("Module(main.line)"), std::string::npos);
85 EXPECT_NE(surface->text.find("Function(add)"), std::string::npos);
86 EXPECT_NE(surface->text.find("Global(answer)"), std::string::npos);
87 const auto * linkage = driver.find_artifact("modules.linkage");
88 ASSERT_NE(linkage, nullptr);
89 EXPECT_NE(linkage->text.find("ModuleLinkage"), std::string::npos);
90 EXPECT_NE(linkage->text.find("Module(main.line) order=1"), std::string::npos);
91 EXPECT_NE(linkage->text.find("Visible(Function(add)) from math.line imported"),
92 std::string::npos);
93 EXPECT_NE(linkage->text.find("Visible(Global(answer)) from main.line local"),
94 std::string::npos);
95 const auto * binding = driver.find_artifact("modules.binding");
96 ASSERT_NE(binding, nullptr);
97 EXPECT_NE(binding->text.find("ModuleBindings"), std::string::npos);
98 EXPECT_NE(binding->text.find("Bind(Function(add)) -> math.line imported"),
99 std::string::npos);
100 EXPECT_NE(binding->text.find("Bind(Global(answer)) -> main.line local"),
101 std::string::npos);
102 const auto * names = driver.find_artifact("modules.names");
103 ASSERT_NE(names, nullptr);
104 EXPECT_NE(names->text.find("ModuleNameTable"), std::string::npos);
105 EXPECT_NE(names->text.find("Name(Function(add)) -> math.line imported"),
106 std::string::npos);
107 const auto * semantic = driver.find_artifact("modules.semantic");
108 ASSERT_NE(semantic, nullptr);
109 EXPECT_NE(semantic->text.find("ModuleSemanticEnvironment"), std::string::npos);
110 EXPECT_NE(semantic->text.find("Value(Function(add)) -> math.line imported"),
111 std::string::npos);
112 ASSERT_EQ(frontend.module_metadata().size(), 2u);
113
114 const auto * hir_artifact = driver.find_artifact("hir");
115 ASSERT_NE(hir_artifact, nullptr);
116 EXPECT_NE(hir_artifact->text.find("HIRModule"), std::string::npos);
117}
118
120{
123
125 bytecode_driver.execute_sources(make_line_inputs(), Compiler_Driver_Action::Emit_Bytecode));
126 ASSERT_NE(bytecode_driver.bytecode_module(), nullptr);
127
128 const auto * bytecode = bytecode_driver.find_artifact("bytecode");
129 ASSERT_NE(bytecode, nullptr);
130 EXPECT_NE(bytecode->text.find("BytecodeModule"), std::string::npos);
131
134 options.c_backend_options.module_name = "line_driver_demo";
135 options.c_backend_options.emit_main = true;
136
138 ASSERT_TRUE(c_driver.execute_sources(make_line_inputs(), Compiler_Driver_Action::Emit_C));
139 ASSERT_TRUE(c_driver.c_emission().valid);
140
141 const auto * c_artifact = c_driver.find_artifact("emit-c");
142 ASSERT_NE(c_artifact, nullptr);
143 EXPECT_NE(c_artifact->text.find("main(void)"), std::string::npos);
144 EXPECT_NE(c_artifact->text.find("line_driver_demo"), std::string::npos);
145}
146
148{
150 inputs.append({"main.line", "let answer = call missing 1 2\n"});
151
154
155 EXPECT_FALSE(driver.execute_sources(inputs, Compiler_Driver_Action::Run));
156 ASSERT_NE(frontend.diagnostic_engine(), nullptr);
157 EXPECT_TRUE(frontend.diagnostic_engine()->has_errors());
158
159 const auto * diagnostics = driver.find_artifact("diagnostics");
160 ASSERT_NE(diagnostics, nullptr);
161 EXPECT_NE(diagnostics->text.find("LIN015"), std::string::npos);
162}
163
165{
167 inputs.append({"helper.line", "func hidden x y = add x y\n"});
168 inputs.append({"main.line", "let answer = call hidden 1 2\n"});
169
172
173 EXPECT_FALSE(driver.execute_sources(inputs, Compiler_Driver_Action::Run));
174 ASSERT_NE(frontend.diagnostic_engine(), nullptr);
175 EXPECT_TRUE(frontend.diagnostic_engine()->has_errors());
176
177 const auto * diagnostics = driver.find_artifact("diagnostics");
178 ASSERT_NE(diagnostics, nullptr);
179 EXPECT_NE(diagnostics->text.find("LIN015"), std::string::npos);
180}
181
183{
185 inputs.append({"main.line",
186 "import missing.line\n"
187 "let answer = int 1\n"});
188
191
192 EXPECT_FALSE(driver.execute_sources(inputs, Compiler_Driver_Action::Parse_Only));
193 ASSERT_NE(frontend.diagnostic_engine(), nullptr);
194 EXPECT_TRUE(frontend.diagnostic_engine()->has_errors());
195
196 const auto * diagnostics = driver.find_artifact("diagnostics");
197 ASSERT_NE(diagnostics, nullptr);
198 EXPECT_NE(diagnostics->text.find("LIN017"), std::string::npos);
199}
200
202{
204 inputs.append({"main.line",
205 "func add x y = add x +\n"
206 "let answer = call add 1 )\n"});
207
210
211 EXPECT_FALSE(driver.execute_sources(inputs, Compiler_Driver_Action::Parse_Only));
212 ASSERT_NE(frontend.diagnostic_engine(), nullptr);
213 EXPECT_TRUE(frontend.diagnostic_engine()->has_errors());
214
215 const auto * diagnostics = driver.find_artifact("diagnostics");
216 ASSERT_NE(diagnostics, nullptr);
217 EXPECT_NE(diagnostics->text.find("LIN018"), std::string::npos);
218}
Reusable pipeline driver that operates on any Compiler_Frontend.
Example frontend for a tiny line-oriented language built on reusable contracts.
Reusable orchestration object built on top of Compiler_Frontend.
Small example frontend for a line-oriented language.
T & append()
Allocate a new entry to the end of array.
#define TEST(name)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
static struct argp_option options[]
Definition ntreepic.C:1886
std::string module_name
Prefix used to derive stable C identifiers.
Configuration shared by all runs of Compiler_Generic_Driver.
Compiler_C_Backend_Options c_backend_options
Backend-C emission options used by emit-c.