Skip to content

Commit

Permalink
Implement code generation.
Browse files Browse the repository at this point in the history
  • Loading branch information
artob committed Jun 23, 2024
1 parent 235565e commit e6300fb
Show file tree
Hide file tree
Showing 48 changed files with 1,301 additions and 93 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CXX = clang++
CXXFLAGS = -std=c++2b
CXXFLAGS = -std=c++2b -Wall -Wextra
INSTALL = install
INSTALL_DATA = $(INSTALL) -m 644

Expand Down
148 changes: 148 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
require 'active_support'
require 'know/ontology'
require 'rdf/turtle'
require 'stringio'

include ActiveSupport::Inflector, RDF

ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.irregular 'cafe', 'cafes'
end

task default: %w(codegen)

HEADER = <<~EOF
/* This is free and unencumbered software released into the public domain. */
#pragma once
EOF

file 'src/know/classes.hpp' => %w(../know.ttl) do |t|
ontology = Know::Ontology.load(t.prerequisites.first)
File.open(t.name, 'w') do |out|
out.puts HEADER
out.puts
ontology.classes.each do |klass|
out.puts %Q[#include "classes/#{klass.cpp_file}"]
end
end
end

task :codegen => %w(../know.ttl src/know/classes.hpp) do |t|
ontology = Know::Ontology.load(t.prerequisites.first)
ontology.classes.each do |klass|
filename = underscore(klass.name)
File.open("src/know/classes/#{filename}.hpp", 'w') do |out_file|
top, out = StringIO.new, StringIO.new
includes = {}

includes['cstdint'] = "for std::uint64_t"
includes['ctime'] = "for std::time_t" # TODO
includes['memory'] = "for std::shared_ptr"
includes['string'] = "for std::string"
includes['vector'] = "for std::vector"

# Generate the `know::$CLASS` class definition:
out.puts <<~EOF
class know::#{klass.cpp_name} {
using string = ::std::string;
template<typename T> using shared_ptr = ::std::shared_ptr<T>;
template<typename T> using vector = ::std::vector<T>;
public:
EOF
klass.properties.each do |property|
next if property.cpp_type.nil?
out.puts " #{property.cpp_type} #{property.cpp_name};"
end
out.puts unless klass.properties.empty?
out.puts " inline virtual ~#{klass.cpp_name}() = default;"

# Generate the `know::$CLASS#clone()` method:
out.puts
out.puts <<~EOF.lines.each { |s| s.prepend(' '*2) }.join
inline virtual shared_ptr<#{klass.cpp_name}> clone() const {
auto clone = std::make_shared<#{klass.cpp_name}>();
EOF
klass.properties.each do |property|
next if property.cpp_type.nil?
out.puts <<~EOF.lines.each { |s| s.prepend(' '*4) }.join
clone->#{property.cpp_name} = this->#{property.cpp_name};
EOF
end
out.puts <<~EOF.lines.each { |s| s.prepend(' '*2) }.join
return clone;
}
EOF

out.puts "};"

# Begin generating the file header:
top.puts HEADER

# Generate standard library dependencies:
top.puts unless includes.empty?
includes.each do |header, comment|
header = "<#{header}>"
top.puts "#include #{header.ljust(9)} // #{comment}"
end

# Generate internal dependencies:
top.puts unless klass.dependencies.empty?
klass.dependencies.each do |dependency|
top.puts "#include \"#{dependency.cpp_name}.hpp\""
end

top.puts
top.puts "namespace know {"
top.puts " class #{klass.cpp_name};"
klass.dependencies.each do |dependency|
top.puts " class #{dependency.cpp_name};"
end
top.puts "}"
top.puts

out_file.write top.string
out_file.write out.string
end
end
end

class Know::Ontology::Class
def cpp_file
"#{underscore(self.name.to_s)}.hpp"
end

def cpp_name
case self.name
when :Class then 'class_'
else underscore(self.name.to_s)
end
end

def cpp_type
"know::#{self.cpp_name}"
end
end

class Know::Ontology::Property
def cpp_name
name = underscore(self.name.to_s)
name = pluralize(name) unless self.functional?
name
end

def cpp_type
type = case type = self.range
when ::Know::Ontology::Class then "shared_ptr<know::#{type.cpp_name}>"
when ::XSD.anyURI then 'string'
when ::XSD.dateTime then 'std::time_t' # TODO
when ::XSD.language then 'string'
when ::XSD.nonNegativeInteger then 'std::uint64_t'
when ::XSD.string then 'string'
else return nil
end
type = "vector<#{type}>" unless self.functional?
type
end
end
24 changes: 22 additions & 2 deletions src/know/classes/activity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#pragma once

namespace know { class activity; }
#include <cstdint> // for std::uint64_t
#include <ctime> // for std::time_t
#include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector

#include "event.hpp"

namespace know {
class activity;
class event;
}

class know::activity {
using string = ::std::string;
template<typename T> using shared_ptr = ::std::shared_ptr<T>;
template<typename T> using vector = ::std::vector<T>;

public:
virtual ~activity() = default;
inline virtual ~activity() = default;

inline virtual shared_ptr<activity> clone() const {
auto clone = std::make_shared<activity>();
return clone;
}
};
24 changes: 22 additions & 2 deletions src/know/classes/airport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#pragma once

namespace know { class airport; }
#include <cstdint> // for std::uint64_t
#include <ctime> // for std::time_t
#include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector

#include "place.hpp"

namespace know {
class airport;
class place;
}

class know::airport {
using string = ::std::string;
template<typename T> using shared_ptr = ::std::shared_ptr<T>;
template<typename T> using vector = ::std::vector<T>;

public:
virtual ~airport() = default;
inline virtual ~airport() = default;

inline virtual shared_ptr<airport> clone() const {
auto clone = std::make_shared<airport>();
return clone;
}
};
24 changes: 22 additions & 2 deletions src/know/classes/appointment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#pragma once

namespace know { class appointment; }
#include <cstdint> // for std::uint64_t
#include <ctime> // for std::time_t
#include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector

#include "event.hpp"

namespace know {
class appointment;
class event;
}

class know::appointment {
using string = ::std::string;
template<typename T> using shared_ptr = ::std::shared_ptr<T>;
template<typename T> using vector = ::std::vector<T>;

public:
virtual ~appointment() = default;
inline virtual ~appointment() = default;

inline virtual shared_ptr<appointment> clone() const {
auto clone = std::make_shared<appointment>();
return clone;
}
};
24 changes: 22 additions & 2 deletions src/know/classes/birth.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#pragma once

namespace know { class birth; }
#include <cstdint> // for std::uint64_t
#include <ctime> // for std::time_t
#include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector

#include "event.hpp"

namespace know {
class birth;
class event;
}

class know::birth {
using string = ::std::string;
template<typename T> using shared_ptr = ::std::shared_ptr<T>;
template<typename T> using vector = ::std::vector<T>;

public:
virtual ~birth() = default;
inline virtual ~birth() = default;

inline virtual shared_ptr<birth> clone() const {
auto clone = std::make_shared<birth>();
return clone;
}
};
24 changes: 22 additions & 2 deletions src/know/classes/birthday.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#pragma once

namespace know { class birthday; }
#include <cstdint> // for std::uint64_t
#include <ctime> // for std::time_t
#include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector

#include "event.hpp"

namespace know {
class birthday;
class event;
}

class know::birthday {
using string = ::std::string;
template<typename T> using shared_ptr = ::std::shared_ptr<T>;
template<typename T> using vector = ::std::vector<T>;

public:
virtual ~birthday() = default;
inline virtual ~birthday() = default;

inline virtual shared_ptr<birthday> clone() const {
auto clone = std::make_shared<birthday>();
return clone;
}
};
24 changes: 22 additions & 2 deletions src/know/classes/birthday_party.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#pragma once

namespace know { class birthday_party; }
#include <cstdint> // for std::uint64_t
#include <ctime> // for std::time_t
#include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector

#include "party.hpp"

namespace know {
class birthday_party;
class party;
}

class know::birthday_party {
using string = ::std::string;
template<typename T> using shared_ptr = ::std::shared_ptr<T>;
template<typename T> using vector = ::std::vector<T>;

public:
virtual ~birthday_party() = default;
inline virtual ~birthday_party() = default;

inline virtual shared_ptr<birthday_party> clone() const {
auto clone = std::make_shared<birthday_party>();
return clone;
}
};
24 changes: 22 additions & 2 deletions src/know/classes/buddhist_temple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#pragma once

namespace know { class buddhist_temple; }
#include <cstdint> // for std::uint64_t
#include <ctime> // for std::time_t
#include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector

#include "temple.hpp"

namespace know {
class buddhist_temple;
class temple;
}

class know::buddhist_temple {
using string = ::std::string;
template<typename T> using shared_ptr = ::std::shared_ptr<T>;
template<typename T> using vector = ::std::vector<T>;

public:
virtual ~buddhist_temple() = default;
inline virtual ~buddhist_temple() = default;

inline virtual shared_ptr<buddhist_temple> clone() const {
auto clone = std::make_shared<buddhist_temple>();
return clone;
}
};
Loading

0 comments on commit e6300fb

Please sign in to comment.