MLLIF
a MLIR-based Language to Language Interoperability Flyover
Loading...
Searching...
No Matches
Decl.cxx
Go to the documentation of this file.
1/*
2 * Copyright 2025 Yeong-won Seo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "pch.h"
18
19#include <cstring>
21#include <mllif/Backend/Decl.h>
22
23mllif::Type::Type(MLLIFContext &context, std::string name) : _refs(0) {
24 while (name.ends_with('*')) {
25 name.erase(name.size() - 1);
26 _refs++;
27 }
28 if (name.contains('*')) {
29 context.error("identifier cannot contain '*' in middle of itself");
30 return;
31 }
32
33 if (name.starts_with('/')) {
34 name.erase(0, 1);
35 std::stringstream ss(name);
36 for (std::string term; std::getline(ss, term, '/');) {
37 _terms.push_back(term);
38 }
39 } else {
40 _builtin = true;
41 _terms.push_back(name);
42 }
43}
44
45mllif::Decl::Decl(MLLIFContext &context, const rapidxml::xml_node<> *node, std::shared_ptr<Decl> parent) : _parent(parent) {
46 if (strcmp(node->name(), "assembly") == 0) {
47 _name = "";
48 return;
49 }
50
51 const auto name = node->first_attribute("id");
52 if (!name) {
53 context.error("identifier missing in declaration");
54 return;
55 }
56
57 _name = name->value();
58}
59
60std::shared_ptr<mllif::Decl> mllif::Decl::Create(MLLIFContext &context, rapidxml::xml_node<> *node, std::shared_ptr<Decl> parent) {
61#define NODE_HANDLER MLLIFContext &context, rapidxml::xml_node<> *node, std::shared_ptr<Decl> parent
62#define NODE_INIT(t) [](NODE_HANDLER) -> std::shared_ptr<Decl> { return std::make_shared<t##Decl>(context, node, parent); }
63 std::map<std::string, std::shared_ptr<Decl> (*)(NODE_HANDLER)> handlers = {
64 {"assembly", NODE_INIT(Assembly)},
65 {"namespace", NODE_INIT(Namespace)},
66 {"object", NODE_INIT(Object)},
67 {"method", NODE_INIT(Method)},
68 {"function", NODE_INIT(Function)},
69 {"param", NODE_INIT(Param)}
70 };
71#undef NODE_INIT
72#undef NODE_HANDLER
73
74 if (!handlers.contains(node->name())) {
75 context.error(std::format("unrecognized tag '{}'", node->name()));
76 return nullptr;
77 }
78
79 auto decl = handlers[node->name()](context, node, parent);
80 if (!context) {
81 return decl;
82 }
83
84 for (auto child = node->first_node(); child; child = child->next_sibling()) {
85 decl->_children.push_back(Create(context, child, parent));
86 }
87
88 return decl;
89}
90
91mllif::ObjectDecl::ObjectDecl(MLLIFContext &context, const rapidxml::xml_node<> *node, std::shared_ptr<Decl> parent) : Decl(context, node, parent) {
92 const auto size = node->first_attribute("size");
93 const auto align = node->first_attribute("align");
94
95 _size = size ? size->value() : "1";
96 _align = align ? align->value() : "1";
97}
98
99mllif::FunctionDecl::FunctionDecl(MLLIFContext &context, const rapidxml::xml_node<> *node, std::shared_ptr<Decl> parent) : Decl(context, node, parent) {
100 const auto returns = node->first_attribute("ret");
101 const auto sym = node->first_attribute("sym");
102
103 if (!returns) {
104 context.error(std::format("return type missing for function '{}'", name()));
105 }
106 if (!sym) {
107 context.error(std::format("symbol name missing for function '{}'", name()));
108 }
109 if (!returns || !sym) {
110 return;
111 }
112
113 _returns = Type(context, returns->value());
114 _symbol = sym->value();
115}
116
117mllif::ParamDecl::ParamDecl(MLLIFContext &context, const rapidxml::xml_node<> *node, std::shared_ptr<Decl> parent) : Decl(context, node, parent) {
118 const auto type = node->first_attribute("type");
119 if (!type) {
120 context.error(std::format("type missing for parameter '{}'", name()));
121 return;
122 }
123
124 _type = Type(context, type->value());
125}
#define NODE_INIT(t)
#define NODE_HANDLER
static std::shared_ptr< Decl > Create(MLLIFContext &context, rapidxml::xml_node<> *node, std::shared_ptr< Decl > parent)
Definition Decl.cxx:60
const std::shared_ptr< Decl > & parent() const
Definition Decl.h:51
Decl(MLLIFContext &context, const rapidxml::xml_node<> *node, std::shared_ptr< Decl > parent)
Definition Decl.cxx:45
const std::string & name() const
Definition Decl.h:49
FunctionDecl(MLLIFContext &context, const rapidxml::xml_node<> *node, std::shared_ptr< Decl > parent)
Definition Decl.cxx:99
const Type & returns() const
Definition Decl.h:84
void error(const std::string &what)
Definition Context.h:35
ObjectDecl(MLLIFContext &context, const rapidxml::xml_node<> *node, std::shared_ptr< Decl > parent)
Definition Decl.cxx:91
const std::string & align() const
Definition Decl.h:74
const std::string & size() const
Definition Decl.h:73
const Type & type() const
Definition Decl.h:99
ParamDecl(MLLIFContext &context, const rapidxml::xml_node<> *node, std::shared_ptr< Decl > parent)
Definition Decl.cxx:117
Type()=default