-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:tamdaz/crygen
- Loading branch information
Showing
3 changed files
with
307 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
require "./spec_helper" | ||
|
||
describe Crygen::Types::LibC do | ||
it "creates a C library" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with one function" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_function("getch", "Int32") | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
fun getch : Int32 | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with one function and a parameter" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_function("getch", "Int32", [{"arg", "String"}]) | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
fun getch(arg : String) : Int32 | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with one function and more parameters" do | ||
args = [ | ||
{"arg", "String"}, | ||
{"value", "Int32"}, | ||
] | ||
|
||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_function("getch", "Int32", args) | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
fun getch(arg : String, value : Int32) : Int32 | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with many functions" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_function("getch", "Int32") | ||
libc_type.add_function("time", "Int32") | ||
libc_type.add_function("getpid", "Int32") | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
fun getch : Int32 | ||
fun time : Int32 | ||
fun getpid : Int32 | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with one struct" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_struct("TimeZone", [ | ||
{"field_one", "Int32"}, | ||
{"field_two", "Int32"}, | ||
]) | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
struct TimeZone | ||
field_one : Int32 | ||
field_two : Int32 | ||
end | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with many structs" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_struct("TimeZone", [ | ||
{"field_one", "Int32"}, | ||
{"field_two", "Int32"}, | ||
]) | ||
|
||
libc_type.add_struct("DateTime", [ | ||
{"timestamp", "Int64"}, | ||
]) | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
struct TimeZone | ||
field_one : Int32 | ||
field_two : Int32 | ||
end | ||
struct DateTime | ||
timestamp : Int64 | ||
end | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with one union" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_union("IntOrFloat", [ | ||
{"some_int", "Int32"}, | ||
{"some_float", "Float64"}, | ||
]) | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
union IntOrFloat | ||
some_int : Int32 | ||
some_float : Float64 | ||
end | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with many unions" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_union("IntOrFloat", [ | ||
{"some_int", "Int32"}, | ||
{"some_float", "Float64"}, | ||
]) | ||
libc_type.add_union("CharOrString", [ | ||
{"some_char", "Char"}, | ||
{"some_string", "String"}, | ||
]) | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
union IntOrFloat | ||
some_int : Int32 | ||
some_float : Float64 | ||
end | ||
union CharOrString | ||
some_char : Char | ||
some_string : String | ||
end | ||
end | ||
CRYSTAL | ||
end | ||
|
||
it "creates a C library with functions, structs and unions" do | ||
libc_type = Crygen::Types::LibC.new("C") | ||
libc_type.add_function("getch", "Int32") | ||
libc_type.add_function("time", "Int32") | ||
libc_type.add_function("getpid", "Int32") | ||
libc_type.add_struct("TimeZone", [ | ||
{"field_one", "Int32"}, | ||
{"field_two", "Int32"}, | ||
]) | ||
libc_type.add_struct("DateTime", [ | ||
{"timestamp", "Int64"}, | ||
]) | ||
libc_type.add_union("IntOrFloat", [ | ||
{"some_int", "Int32"}, | ||
{"some_float", "Float64"}, | ||
]) | ||
libc_type.add_union("CharOrString", [ | ||
{"some_char", "Char"}, | ||
{"some_string", "String"}, | ||
]) | ||
libc_type.generate.should eq(<<-CRYSTAL) | ||
lib C | ||
struct TimeZone | ||
field_one : Int32 | ||
field_two : Int32 | ||
end | ||
struct DateTime | ||
timestamp : Int64 | ||
end | ||
union IntOrFloat | ||
some_int : Int32 | ||
some_float : Float64 | ||
end | ||
union CharOrString | ||
some_char : Char | ||
some_string : String | ||
end | ||
fun getch : Int32 | ||
fun time : Int32 | ||
fun getpid : Int32 | ||
end | ||
CRYSTAL | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
require "./../interfaces/generator" | ||
require "./../types/*" | ||
|
||
# A class that generates a C library. | ||
# ``` | ||
# libc_type = Crygen::Types::LibC.new("C") | ||
# libc_type.add_function("getch", "Int32") | ||
# libc_type.generate | ||
# ``` | ||
# Output : | ||
# ``` | ||
# lib C | ||
# fun getch : Int32 | ||
# end | ||
# ``` | ||
class Crygen::Types::LibC < Crygen::Abstract::GeneratorInterface | ||
alias FieldArray = Array(Tuple(String, String)) | ||
|
||
@functions = [] of Hash(Symbol, String) | ||
@objects = [] of Tuple(String, Symbol, FieldArray) | ||
|
||
def initialize(@name : String); end | ||
|
||
# Adds a C function (name and return type). | ||
def add_function(name : String, return_type : String, args : Array(Tuple(String, String)) | Nil = nil) : Nil | ||
@functions << { | ||
:name => name, | ||
:args => !args.nil? ? generate_args(args) : "", | ||
:return_type => return_type, | ||
} | ||
end | ||
|
||
# Adds a struct. | ||
def add_struct(name : String, fields : FieldArray) : Nil | ||
@objects << {name, :struct, fields} | ||
end | ||
|
||
# Adds an union. | ||
def add_union(name : String, fields : FieldArray) : Nil | ||
@objects << {name, :union, fields} | ||
end | ||
|
||
# Generates a C lib. | ||
def generate : String | ||
String.build do |str| | ||
str << "lib #{@name}\n" | ||
can_add_whitespace = false | ||
@objects.each do |object| | ||
str << "\n" if can_add_whitespace == true | ||
str << " #{object[1]} #{object[0]}\n" | ||
object[2].each do |field| | ||
str << " #{field[0]} : #{field[1]}\n" | ||
end | ||
str << " end\n" | ||
can_add_whitespace = true | ||
end | ||
str << "\n" if !@objects.empty? && !@functions.empty? | ||
@functions.each do |function| | ||
if function[:args].empty? | ||
str << " fun #{function[:name]} : #{function[:return_type]}\n" | ||
else | ||
str << " fun #{function[:name]}#{function[:args]} : #{function[:return_type]}\n" | ||
end | ||
end | ||
str << "end" | ||
end | ||
end | ||
|
||
# Generate the args. | ||
private def generate_args(args : Array(Tuple(String, String))) : String | ||
String.build do |str| | ||
str << '(' | ||
args.each_with_index do |arg, i| | ||
str << "#{arg[0]} : #{arg[1]}" | ||
str << ", " if i != args.size - 1 | ||
end | ||
str << ')' | ||
end | ||
end | ||
end |