Skip to content

Instantly share code, notes, and snippets.

@blambeau
Created March 9, 2014 18:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blambeau/9452008 to your computer and use it in GitHub Desktop.
Save blambeau/9452008 to your computer and use it in GitHub Desktop.
Q -- Abstract Syntax Tree
[
:system,
[
:type_def,
"Boolean",
[
:union_type,
[
:builtin_type,
"TrueClass"
],
[
:builtin_type,
"FalseClass"
]
]
],
[
:type_def,
"String",
[
:builtin_type,
"String"
]
],
[
:type_def,
"Real",
[
:builtin_type,
"Float"
]
],
[
:type_def,
"Integer",
[
:builtin_type,
"Fixnum"
]
],
[
:type_def,
"Date",
[
:ad_type,
"Date",
[
:contract,
"iso8601",
[
:builtin_type,
"String"
],
[
:inline_pair,
[
:fn,
[
:parameters,
"s"
],
[
:source,
"Date.iso8601(s)"
]
],
[
:fn,
[
:parameters,
"t"
],
[
:source,
"t.iso8601"
]
]
]
]
]
],
[
:type_def,
"Time",
[
:ad_type,
"Time",
[
:contract,
"iso8601",
[
:builtin_type,
"String"
],
[
:inline_pair,
[
:fn,
[
:parameters,
"s"
],
[
:source,
"DateTime.parse(s)"
]
],
[
:fn,
[
:parameters,
"t"
],
[
:source,
"t.iso8601"
]
]
]
]
]
],
[
:type_def,
"Uuid",
[
:sub_type,
[
:type_ref,
"String"
],
[
:constraint,
"default",
[
:fn,
[
:parameters,
"s"
],
[
:source,
"s.size == 36"
]
]
]
]
],
[
:type_def,
"Dose",
[
:ad_type,
nil,
[
:contract,
"as",
[
:sub_type,
[
:type_ref,
"Real"
],
[
:constraint,
"default",
[
:fn,
[
:parameters,
"f"
],
[
:source,
"f >= 0.0 and f <= 1.0"
]
]
]
]
]
]
],
[
:type_def,
"Gender",
[
:ad_type,
nil,
[
:contract,
"as",
[
:sub_type,
[
:type_ref,
"String"
],
[
:constraint,
"default",
[
:fn,
[
:parameters,
"s"
],
[
:source,
"s == 'M' or s == 'F'"
]
]
]
]
]
]
],
[
:type_def,
"Duration",
[
:ad_type,
nil,
[
:contract,
"minutes",
[
:sub_type,
[
:type_ref,
"Integer"
],
[
:constraint,
"default",
[
:fn,
[
:parameters,
"i"
],
[
:source,
"i > 0"
]
]
]
]
]
]
],
[
:type_def,
"Name",
[
:sub_type,
[
:type_ref,
"String"
],
[
:constraint,
"default",
[
:fn,
[
:parameters,
"s"
],
[
:source,
"s.strip.size > 0"
]
]
]
]
],
[
:type_def,
"Appointment",
[
:tuple_type,
[
:heading,
[
:attribute,
"at",
[
:type_ref,
"Time"
]
],
[
:attribute,
"duration",
[
:type_ref,
"Duration"
]
],
[
:attribute,
"fixed",
[
:type_ref,
"Boolean"
]
]
]
]
],
[
:relation_type,
[
:heading,
[
:attribute,
"id",
[
:type_ref,
"Uuid"
]
],
[
:attribute,
"diagnosis_date",
[
:type_ref,
"Date"
]
],
[
:attribute,
"patient",
[
:tuple_type,
[
:heading,
[
:attribute,
"id",
[
:type_ref,
"Uuid"
]
],
[
:attribute,
"name",
[
:type_ref,
"Name"
]
],
[
:attribute,
"gender",
[
:type_ref,
"Gender"
]
]
]
]
],
[
:attribute,
"appointments",
[
:set_type,
[
:type_ref,
"Appointment"
]
]
]
]
]
]
require 'qrb'
require 'awesome_print'
ap Qrb.ast(File.read('schema.q')), index: false
# Mapping with the host language (can be provided by Qrb itself)
Boolean = .TrueClass|.FalseClass
String = .String
Real = .Float
Integer = .Fixnum
Date = .Date <iso8601> .String \( s | Date.iso8601(s) )
\( t | t.iso8601 )
Time = .Time <iso8601> .String \( s | DateTime.parse(s) )
\( t | t.iso8601 )
# Some reusable data types (could be reused across schemas)
Uuid = String( s | s.size == 36 )
Dose = <as> Real( f | f >= 0.0 and f <= 1.0 )
Gender = <as> String( s | s == 'M' or s == 'F' )
Duration = <minutes> Integer( i | i > 0 )
Name = String( s | s.strip.size > 0 )
Appointment = {
at: Time,
duration: Duration,
fixed: Boolean
}
# The main schema, for instance for a RESTful resource or a NoSQL
# database
{{
id: Uuid,
diagnosis_date: Date,
patient: {
id: Uuid,
name: Name,
gender: Gender
},
appointments: {Appointment}
}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment