Skip to content

Commit fbf4b02

Browse files
committed
4.0.2
1 parent 83680e3 commit fbf4b02

File tree

3 files changed

+220
-47
lines changed

3 files changed

+220
-47
lines changed

lib/conversions/src/RLCToRuby.cpp

Lines changed: 154 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ limitations under the License.
2727
#include "rlc/utils/PatternMatcher.hpp"
2828
namespace mlir::rlc
2929
{
30+
static bool isUserDefined(mlir::Type type)
31+
{
32+
return (
33+
type and
34+
(mlir::isa<mlir::rlc::ClassType>(decayCtxFrmType(type)) or
35+
mlir::isa<mlir::rlc::AlternativeType>(decayCtxFrmType(type))));
36+
}
3037
static void printCFunDecl(
3138
StreamWriter& writer, mlir::FunctionType type, llvm::StringRef name)
3239
{
@@ -210,6 +217,11 @@ namespace mlir::rlc
210217

211218
bool isStringArg =
212219
mlir::isa_and_nonnull<mlir::rlc::StringLiteralType>(type);
220+
if (type.isa_and_nonnull<mlir::rlc::StringLiteralType>())
221+
{
222+
printArgName(writer, name);
223+
return;
224+
}
213225
if (type != nullptr and builtinCType(type))
214226
{
215227
writer.write("RLC::rlc_convert_to_");
@@ -263,6 +275,7 @@ namespace mlir::rlc
263275
w.write("c");
264276
})
265277
.Case([&](mlir::rlc::BoolType t) { w.write("c"); })
278+
.Case([&](mlir::rlc::FloatType t) { w.write("d"); })
266279
.Case([&](mlir::rlc::ReferenceType t) { w.write("J"); })
267280
.Default([](mlir::Type t) {
268281
t.dump();
@@ -284,6 +297,9 @@ namespace mlir::rlc
284297
.Case([&](mlir::rlc::ReferenceType t) {
285298
w.write("Fiddle::SIZEOF_VOIDP");
286299
})
300+
.Case([&](mlir::rlc::StringLiteralType t) {
301+
w.write("Fiddle::SIZEOF_VOIDP");
302+
})
287303
.Case(
288304
[&](mlir::rlc::ClassType t) { w.write(t.mangledName(), ".size"); })
289305
.Case([&](mlir::rlc::AliasType t) {
@@ -345,6 +361,12 @@ namespace mlir::rlc
345361
{
346362
w.writenl("__to_return");
347363
}
364+
else if (resultType.isa<mlir::rlc::StringLiteralType>())
365+
{
366+
w.write("__result[0, ");
367+
printTypeSize(w, resultType);
368+
w.write("].to_s");
369+
}
348370
else
349371
{
350372
w.write("__result[0, ");
@@ -565,7 +587,10 @@ namespace mlir::rlc
565587
}
566588
if (auto casted = type.dyn_cast<mlir::rlc::AlternativeType>())
567589
{
568-
w.write("{", name, ": RLC_", casted.getMangledName(), "}");
590+
w.write("{", name, ": ");
591+
w.write("RLC_");
592+
w.writeType(casted);
593+
w.write("}");
569594
return;
570595
}
571596
if (auto casted = type.dyn_cast<mlir::rlc::ArrayType>())
@@ -601,19 +626,6 @@ namespace mlir::rlc
601626
}
602627
}
603628

604-
static void emitMembers(
605-
llvm::ArrayRef<mlir::Type> types,
606-
mlir::rlc::StreamWriter& w,
607-
MemberFunctionsTable& table)
608-
{
609-
for (auto iter : llvm::enumerate(types))
610-
{
611-
w.write("(\"_alternative", iter.index(), "\", ");
612-
w.writeType(iter.value(), 1);
613-
w.write("), ");
614-
}
615-
}
616-
617629
static void emitHinting(
618630
llvm::ArrayRef<mlir::Type> types,
619631
llvm::ArrayRef<llvm::StringRef> memberNames,
@@ -658,6 +670,8 @@ namespace mlir::rlc
658670
llvm::drop_begin(llvm::enumerate(overload.getInputs()), isMethod))
659671
{
660672
w.write(" and args[", argument.index() - isMethod, "].class == ");
673+
if (isUserDefined(argument.value()))
674+
w.write("RLC::");
661675
w.writeType(argument.value());
662676
}
663677
w.endLine();
@@ -701,7 +715,8 @@ namespace mlir::rlc
701715
}
702716
if (auto clsType = attr.getType().dyn_cast<mlir::rlc::AlternativeType>())
703717
{
704-
w.write(clsType.getMangledName(), ".new(");
718+
w.writeType(clsType);
719+
w.write(".new(");
705720
w.write("@content.", attr.getName(), ")");
706721
return;
707722
}
@@ -780,6 +795,52 @@ namespace mlir::rlc
780795
}
781796
}
782797

798+
static void emitMembers(
799+
llvm::ArrayRef<mlir::Type> types,
800+
mlir::rlc::StreamWriter& w,
801+
MemberFunctionsTable& table)
802+
{
803+
size_t i = 1;
804+
for (auto type : types)
805+
{
806+
emitMemberType(w, type, ("_alternative" + llvm::Twine(i - 1)).str());
807+
if (i++ != types.size())
808+
{
809+
w.write(",");
810+
}
811+
w.endLine();
812+
}
813+
}
814+
815+
static void emitFiddleDeclaration(
816+
mlir::rlc::AlternativeType type,
817+
mlir::rlc::StreamWriter& w,
818+
MemberFunctionsTable& table,
819+
mlir::rlc::ModuleBuilder& builder,
820+
mlir::rlc::EnumDeclarationOp enumDeclaration = nullptr)
821+
{
822+
w.write("RLC_");
823+
w.writeType(type);
824+
w.writenl("_impl = union([");
825+
{
826+
auto _ = w.indent();
827+
emitMembers(type.getUnderlying(), w, table);
828+
}
829+
w.writenl("])");
830+
831+
w.write("RLC_");
832+
w.writeType(type);
833+
w.writenl(" = struct([");
834+
{
835+
auto _ = w.indent();
836+
w.write("{_data:MyLib::RLC_");
837+
w.writeType(type);
838+
w.writenl("_impl},");
839+
w.writenl("{active_index:MyLib::RLC_int}");
840+
}
841+
w.writenl("])");
842+
}
843+
783844
static void emitFiddleDeclaration(
784845
mlir::rlc::ClassType type,
785846
mlir::rlc::StreamWriter& w,
@@ -809,6 +870,10 @@ namespace mlir::rlc
809870
{
810871
emitFiddleDeclaration(casted, w, table, builder);
811872
}
873+
if (auto casted = mlir::dyn_cast<mlir::rlc::AlternativeType>(t))
874+
{
875+
emitFiddleDeclaration(casted, w, table, builder);
876+
}
812877
}
813878
}
814879

@@ -888,7 +953,24 @@ namespace mlir::rlc
888953

889954
writer.writenl("def rlc_convert_to_Float(value = 0)");
890955
writer.writenl("\tp = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT)");
891-
writer.writenl("\tp[0, Fiddle::SIZEOF_DOUBLE] = [value].pack(\"q\")");
956+
writer.writenl("\tp[0, Fiddle::SIZEOF_DOUBLE] = [value].pack(\"d\")");
957+
writer.writenl("end");
958+
959+
writer.writenl("def to_ruby_str str");
960+
writer.writenl("\tstr.__rlc_data._data._data.content.to_s");
961+
writer.writenl("end");
962+
writer.writenl("def to_rlc_str str");
963+
writer.writenl("\tout = RLC::String.new");
964+
writer.writenl("\ts_lit = str.encode(\"UTF-8\")");
965+
writer.writenl(
966+
"\tptr = "
967+
"Fiddle::Pointer.malloc(s_lit.bytesize + 1)");
968+
writer.writenl("\tptr[0, s_lit.bytesize] = s_lit");
969+
writer.writenl("\tptr[s_lit.bytesize, 1] = \"\\0\"");
970+
writer.writenl("\ts = MyLib::RLC_string_lit.malloc");
971+
writer.writenl("\ts.content = ptr");
972+
writer.writenl("\tRLC::append_to_string(s, out)");
973+
writer.writenl("\treturn out");
892974
writer.writenl("end");
893975
}
894976

@@ -898,40 +980,63 @@ namespace mlir::rlc
898980
MemberFunctionsTable& table,
899981
mlir::rlc::ModuleBuilder& builder)
900982
{
901-
w.write("class _");
902-
w.writeType(type);
903-
w.writenl("(ctypes.Union):");
904-
{
905-
auto _ = w.indent();
906-
emitMembers(type.getUnderlying(), w, table);
907-
w.endLine();
908-
}
909983
w.write("class ");
910984
w.writeType(type);
911-
w.writenl("(ctypes.Structure):");
912-
auto _ = w.indent();
913-
914-
w.write("_fields_ = [(\"_content\", _");
915-
w.writeType(type);
916-
w.writenl("), (\"resume_index\", ctypes.c_longlong)]");
917-
918-
emitSpecialFunctions(type, w, table, builder);
919-
920-
w.writenl("def __getitem__(self, key):");
985+
w.endLine();
921986
{
922-
auto _2 = w.indent();
923-
for (auto enumeration : llvm::enumerate(type.getUnderlying()))
987+
auto _ = w.indent();
988+
w.writenl("def __rlc_data");
924989
{
925-
w.write("if key == ");
926-
w.writeType(enumeration.value());
927-
w.writenl(" and self.resume_index == ", enumeration.index(), ":");
928990
auto _ = w.indent();
929-
w.writenl("return self._content._alternative", enumeration.index());
991+
w.write("return @content");
992+
w.endLine();
993+
}
994+
w.writenl("end");
995+
emitSpecialFunctions(type, w, table, builder);
996+
997+
w.writenl("def [](index)");
998+
{
999+
auto _2 = w.indent();
1000+
for (auto enumeration : llvm::enumerate(type.getUnderlying()))
1001+
{
1002+
w.write("if ");
1003+
w.writenl(
1004+
"@content.active_index.content == index and index == ",
1005+
enumeration.index());
1006+
{
1007+
auto _ = w.indent();
1008+
w.write("return ");
1009+
bool isUserDefined = false;
1010+
if (type and (mlir::isa<mlir::rlc::ClassType>(
1011+
decayCtxFrmType(enumeration.value())) or
1012+
mlir::isa<mlir::rlc::AlternativeType>(
1013+
decayCtxFrmType(enumeration.value()))))
1014+
isUserDefined = true;
1015+
1016+
if (not isUserDefined)
1017+
w.writenl(
1018+
"@content._data._alternative",
1019+
enumeration.index(),
1020+
".content");
1021+
else
1022+
{
1023+
w.writeType(enumeration.value());
1024+
w.writenl(
1025+
".new(",
1026+
"@content._data._alternative",
1027+
enumeration.index(),
1028+
")");
1029+
}
1030+
}
1031+
w.writenl("end");
1032+
}
1033+
w.writenl("return nil");
9301034
}
931-
w.writenl("return nil");
1035+
w.writenl("end");
1036+
w.endLine();
1037+
emitMemberFunctions(type, w, table);
9321038
}
933-
w.endLine();
934-
emitMemberFunctions(type, w, table);
1039+
w.writenl("end");
9351040
}
9361041

9371042
class AliasToRubyAlias
@@ -1077,7 +1182,7 @@ namespace mlir::rlc
10771182
});
10781183
matcher.add(
10791184
[&](mlir::rlc::AlternativeType type, llvm::raw_string_ostream& OS) {
1080-
OS << type.getMangledName();
1185+
OS << "RLC" << type.getMangledName();
10811186
});
10821187
}
10831188

@@ -1107,8 +1212,10 @@ namespace mlir::rlc
11071212
[&](mlir::rlc::ReferenceType type, llvm::raw_string_ostream& OS) {
11081213
OS << "MyLib::RLC_voidp";
11091214
});
1110-
matcher.add([](mlir::rlc::StringLiteralType type,
1111-
llvm::raw_string_ostream& OS) { OS << "String"; });
1215+
matcher.add(
1216+
[](mlir::rlc::StringLiteralType type, llvm::raw_string_ostream& OS) {
1217+
OS << "MyLib::RLC_string_lit";
1218+
});
11121219
registerCommonTypeConversion(matcher);
11131220
}
11141221

@@ -1408,7 +1515,7 @@ namespace mlir::rlc
14081515
matcher.getWriter().writenl(
14091516
"actionToAnyFunctionType[\"",
14101517
op.getUnmangledName(),
1411-
"\"] = Any",
1518+
"\"] = RLCAny",
14121519
op.getClassType().getName(),
14131520
"Action");
14141521
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# REQUIRES: has_ruby
2+
# RUN: split-file %s %t
3+
4+
# RUN: rlc %t/source.rl -o %t/lib%sharedext -i %stdlib --shared
5+
# RUN: rlc %t/source.rl -o %t/lib%libext -i %stdlib --compile
6+
7+
# RUN: rlc %t/source.rl -o %t/library.rb -i %stdlib --ruby
8+
# RUN: ruby %t/to_run.rb
9+
10+
11+
#--- source.rl
12+
import collections.vector
13+
import serialization.print
14+
15+
cls Context:
16+
Int x
17+
Int y
18+
19+
@classes
20+
act sequence(ctx Context context) -> Sequence:
21+
frm accumulator : Vector<Int>
22+
while true:
23+
act add(Int z)
24+
accumulator.append(context.x + context.y + z)
25+
print(accumulator)
26+
27+
fun main() -> Int:
28+
let x : Context
29+
from_string(x, to_string(x))
30+
return 0
31+
32+
33+
#--- to_run.rb
34+
require_relative 'library'
35+
ctx = RLC::Context.new
36+
sec = RLC::sequence ctx
37+
str = RLC::to_string ctx
38+
raise "wrong" unless RLC::to_ruby_str(RLC::to_rlc_str(RLC::to_ruby_str(str))) == RLC::to_ruby_str(str)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# REQUIRES: has_ruby
2+
# RUN: split-file %s %t
3+
4+
# RUN: rlc %t/source.rl -o %t/lib%sharedext -i %stdlib --shared
5+
# RUN: rlc %t/source.rl -o %t/lib%libext -i %stdlib --compile
6+
7+
# RUN: rlc %t/source.rl -o %t/library.rb -i %stdlib --ruby
8+
# RUN: ruby %t/to_run.rb
9+
10+
11+
#--- source.rl
12+
cls Pair:
13+
Int | Float x
14+
15+
16+
cls Outer:
17+
Pair inner
18+
19+
#--- to_run.rb
20+
require_relative 'library'
21+
22+
outer = RLC::Outer.new;
23+
outer.inner.x.assign(2.2);
24+
if outer.inner.x[1] != nil
25+
return -10;
26+
end
27+
raise "this is wrong" unless outer.inner.x[1] - 2.2
28+

0 commit comments

Comments
 (0)