Skip to content

Instantly share code, notes, and snippets.

@pythonesque
Last active August 29, 2015 14:07
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 pythonesque/87bc4a7299ef1f749b6e to your computer and use it in GitHub Desktop.
Save pythonesque/87bc4a7299ef1f749b6e to your computer and use it in GitHub Desktop.
pub mod bitmap {
pub type ColorComponent = u8;
#[deriving(Clone, Default, Eq, PartialEq)]
pub struct Pixel {
pub r: ColorComponent,
pub g: ColorComponent,
pub b: ColorComponent,
}
pub static BLACK: Pixel = Pixel { r: ::std::u8::MIN, g: ::std::u8::MIN, b: ::std::u8::MIN };
pub static WHITE: Pixel = Pixel { r: ::std::u8::MAX, g: ::std::u8::MAX, b: ::std::u8::MAX };
#[deriving(Clone)]
pub struct Image<T> {
width: uint,
height: uint,
buf: Vec<T>,
}
#[deriving(Clone, Eq, PartialEq)]
pub enum ImageError {
DimensionError,
}
pub trait Color: PartialEq {
fn black() -> Self;
fn white() -> Self;
fn is_black(&self) -> bool { *self == Color::black() }
fn is_white(&self) -> bool { *self == Color::white() }
}
impl Pixel {
pub fn new(r: ColorComponent, g: ColorComponent, b: ColorComponent) -> Pixel {
Pixel { r: r, g: g, b: b }
}
}
impl Color for Pixel {
fn black() -> Pixel { BLACK }
fn white() -> Pixel { WHITE }
}
impl<T: Copy + Color> Image<T> {
pub unsafe fn alloc(width: uint, height: uint) -> Result<Image<T>, ImageError> {
match width.checked_mul(&height) {
Some(s) => Ok(Image {
width: width,
height: height,
buf: {
let mut buf = Vec::with_capacity(s);
buf.set_len(s);
buf
},
}),
None => return Err(DimensionError)
}
}
pub fn from_data(data: Vec<T>, width: uint, height: uint) -> Result<Image<T>, ImageError> {
match width.checked_mul(&height) {
Some(s) if s == data.len() => Ok(Image {
width: width,
height: height,
buf: data,
}),
_ => { return Err(DimensionError) }
}
}
pub fn width(&self) -> uint { self.width }
pub fn height(&self) -> uint { self.height }
pub fn get(&self, x: uint, y: uint) -> Option<&T> {
if self.width <= x || self.height <= y {
None
} else {
let ref c = self.buf[y * self.width + x];
Some(c)
}
}
pub fn get_mut(&mut self, x: uint, y: uint) -> Option<&mut T> {
if self.width <= x || self.height <= y {
None
} else {
Some(self.buf.get_mut(y * self.width + x))
}
}
pub fn clear(&mut self, color: T) {
for c in self.buf.iter_mut() {
*c = color;
}
}
}
/*pub trait ImageEncoder<T, E> {
pub fn emit_pixel(&mut self, T) -> Result<T, E>;
pub fn emit_image(&mut self, Image<T>) -> Result<T, E>;
}
pub trait Encodable<S: Encoder<E>, E> {
fn encode(&self, s: &mut S) -> Result<(), E>;
}*/
}
module
pub fn main() {
}
#![feature(unboxed_closures,slicing_syntax)]
use std::io;
#[deriving(Show)]
enum Token<'a> {
Equals,
VBar,
LParen, RParen,
LBracket, RBracket,
LBrace, RBrace,
Semi,
Literal(&'a [Ascii]),
Ident(&'a [Ascii]),
EOF,
}
#[deriving(PartialEq,Show)]
enum Error {
UnterminatedStringLiteral, // Missing an end double quote during string parsing
IoError(io::IoError), // Some other kind of I/O error
IncorrectCloseDelimiter, // ) appeared where it shouldn't (usually as the first token)
UnexpectedEOF, // Usually means a missing ), but could also mean there were no tokens at all.
ExpectedEOF, // More tokens after the list is finished, or after a literal if there is no list.
}
struct Tokens<'a> {
string: &'a [Ascii],
first: Option<Ascii>,
rest: &'a [Ascii],
}
impl<'a> Tokens<'a> {
fn new(string: &'a [Ascii]) -> Tokens {
let (ch, s) = if string.len() == 0 { (None, string) } else {
let (ch, s) = string.split_at(1);
(ch.iter().map(|&ch| ch).next(), s)
};
Tokens { string: string, first: ch, rest: s }
}
// Utility function to update information in the iterator. It might not be performant to keep
// rest cached, but there are times where we don't know exactly what string is (at least, not
// in a way that we can *safely* reconstruct it without allocating), so we keep both here.
// With some unsafe code we could probably get rid of one of them (and maybe first, too).
fn update(&mut self, string: &'a [Ascii]) {
self.string = string;
let (ch, s) = if string.len() == 0 { (None, string) } else {
let (ch, s) = string.split_at(1);
(ch.iter().map(|&ch| ch).next(), s)
};
self.first = ch;
self.rest = s;
}
// This is where the lexing happens. Note that it does not handle string escaping.
fn next(&mut self) -> Result<Token<'a>, Error> {
loop {
match self.first.map ( |ch| ch.to_byte() ) {
// Equals
Some(b'=') => {
self.update(self.rest);
return Ok(Equals)
},
Some(b'|') => {
self.update(self.rest);
return Ok(VBar)
}
// ( start
Some(b'(') => {
self.update(self.rest);
return Ok(LParen)
},
// ) end
Some(b')') => {
self.update(self.rest);
return Ok(RParen)
},
// [ start
Some(b'[') => {
self.update(self.rest);
return Ok(LBracket)
},
// ] end
Some(b']') => {
self.update(self.rest);
return Ok(RBracket)
},
// { start
Some(b'{') => {
self.update(self.rest);
return Ok(LBrace)
},
// } end
Some(b'}') => {
self.update(self.rest);
return Ok(RBrace)
},
// . or ;
Some(b'.') | Some(b';') => {
self.update(self.rest);
return Ok(Semi)
},
// Double quoted literal start
Some(b'"') => {
// Split the string at most once. This lets us get a
// reference to the next piece of the string without having
// to loop through the string again.
let mut iter = self.rest.splitn(1, |&ch| ch == b'"'.to_ascii());
// The first time splitn is run it will never return None, so this is safe.
let str = iter.next().unwrap();
match iter.next() {
// Extract the interior of the string without allocating. If we want to
// handle string escaping, we would have to allocate at some point though.
Some(s) => {
self.update(s);
return Ok(Literal(str))
},
None => return Err(UnterminatedStringLiteral)
}
},
// Single quoted literal start
Some(b'\'') => {
// Split the string at most once. This lets us get a
// reference to the next piece of the string without having
// to loop through the string again.
let mut iter = self.rest.splitn(1, |&ch| ch == b'\''.to_ascii());
// The first time splitn is run it will never return None, so this is safe.
let str = iter.next().unwrap();
match iter.next() {
// Extract the interior of the string without allocating. If we want to
// handle string escaping, we would have to allocate at some point though.
Some(s) => {
self.update(s);
return Ok(Literal(str))
},
None => return Err(UnterminatedStringLiteral)
}
},
// Identifier start
Some(c) => {
// Skip whitespace. This could probably be made more efficient.
match c {
b' ' | b'\x09' ... b'\x0d' => {
self.update(self.rest);
continue
},
_ => (),
}
// Since we've exhausted all other possibilities, this must be a real identifier.
// Unlike the quoted case, it's not an error to encounter EOF before whitespace.
let mut end_ch = None;
let mut len = 0;
let str = {
let mut iter = self.string.iter();
let str;
loop {
let ch = iter.next();
match ch {
Some(ch) => {
len += 1;
let term = match ch.to_byte() {
b'=' | b'|' | b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'.' | b';' | b'"' | b'\'' => true,
_ => false
};
if term { end_ch = Some(ch); }
if term || (match ch.to_byte() { b' ' | b'\x09' ... b'\x0d' => true, _ => false }) {
str = self.string[.. len - 1];
self.rest = self.string[len - 1 .. ];
break;
}
},
None => {
str = self.string;
self.rest = "".to_ascii();
break
}
}
};
str
};
match end_ch {
// self.string will be incorrect in the Some(_) case. The only reason it's
// okay is because the next time next() is called in this case, we know it
// will be '(' or ')', so it will never reach any code that actually looks
// at self.string. In a real implementation this would be enforced by
// visibility rules.
Some(c) => self.first = Some(*c),
None => self.update(self.rest)
}
return Ok(Ident(str));
}
None => return Ok(EOF)
}
}
}
}
fn parse(string: &[Ascii]) -> Result<(), Error> {
let mut tokens = Tokens::new(string);
loop {
let tok = tokens.next();
match try!(tok) {
EOF => return Ok(()),
Ident(s) => println!("Ident({})", s.as_str_ascii()),
Literal(s) => println!("Literal({})", s.as_str_ascii()),
t => println!("{}", t),
}
}
}
fn main() {
const EBNF: &'static [u8] = br#"
"EBNF defined in itself" {
syntax = [ title ] "{" { production } "}" [ comment ].
production = identifier "=" expression ( "." | ";" ) .
expression = term { "|" term } .
term = factor { factor } .
factor = identifier
| literal
| "[" expression "]"
| "(" expression ")"
| "{" expression "}" .
identifier = character { character } .
title = literal .
comment = literal .
literal = "'" character { character } "'"
| '"' character { character } '"' .
}"#;
let ebnf_ascii = EBNF.to_ascii();
parse(ebnf_ascii).unwrap();
}
#![feature(tuple_indexing)]
extern crate time;
use std::default::Default;
use std::f32::consts::PI;
use std::num::{Zero, zero};
use std::sync::{Arc, Mutex};
use std::time::duration::Duration;
use std::io::timer::Timer;
use time::precise_time_ns;
#[deriving(Clone, Default)]
pub struct Ratio<T, U>(T, U);
pub struct Area(f32);
impl Mul<Duration, Area> for
impl Mul<Duration, f32> for Ratio<f32, Duration> {
fn mul(&self, rhs: &Duration) -> f32 {
self.1 * (rhs.num_nanoseconds() / self.0.num_nanoseconds()) as f32
}
}
/*impl<T, U: Div<V, U>, V> Mul<V, T> for Ratio<T, U> {
pub fn mul(&self, rhs: &V) -> T {
}
}*/
//pub struct Integrator<S: Zero, K: Fn<Duration, S>> {
pub struct Integrator<S: Send, T: Send> {
input: Sender<|Duration|: Send -> S>,
output: Arc<Mutex<T>>,
}
impl<S: Default + Mul<Duration, T> + Send + Zero,
T: Clone + Send + Sync + Zero> Integrator<S, T> {
pub fn new(frequency: Duration) -> Integrator<S, T> {
let (tx, input) = channel();
let integrator = Integrator {
input: tx,
output: Arc::new(Mutex::new(zero::<T>())),
};
let s = integrator.output.clone();
spawn(proc() {
let mut timer = match Timer::new() {
Ok(timer) => timer,
Err(_) => return
};
let periodic = timer.periodic(frequency);
let mut t = Duration::nanoseconds(precise_time_ns() as i64);
let mut k = |t| Default::default();
let mut k_0: S = Default::default();
loop {
select! {
res = periodic.recv_opt() => match res {
Ok(_) => {
t = t + frequency;
let k_1: S = k(t);
let mut s = s.lock();
*s = *s + (k_1 * (frequency / 2) + k_0 * (frequency / 2));
}
Err(_) => break,
},
res = input.recv_opt() => match res {
Ok(k_new) => k = k_new,
Err(_) => break,
}
}
}
});
integrator
}
pub fn input(&self, k: |Duration|: Send -> S) -> Result<(), |Duration|: Send -> S> {
self.input.send_opt(k)
}
pub fn output(&self) -> T { self.output.lock().clone() }
}
fn main() {
let f = 1 / Duration::seconds(2).num_milliseconds() as f32;
let object = Integrator::new(Duration::milliseconds(10));
object.input(|t| (PI * 2. * f * t.num_milliseconds()).sin()).unwrap();
}
#[allow(dead_code)]
pub mod ldap {
use self::protocol as p;
use std::collections::HashSet;
mod protocol {
use ldap as l;
use std::collections::HashSet;
// 4.2. Bind Operation
pub struct BindRequest {
version: i8,
name: l::LdapDN,
authentication: AuthenticationChoice,
}
enum AuthenticationChoice {
Simple(Vec<u8>),
Sasl(SaslCredentials),
}
struct SaslCredentials {
mechanism: l::LdapString,
credentials: Option<Vec<u8>>,
}
// 4.2.2. Bind Response
pub struct BindResponse {
ldap_result: l::LdapResult,
server_sasl_creds: Option<Vec<u8>>,
}
// 4.3. Unbind Operation
pub struct UnbindRequest;
// 4.5. Search Operation
// 4.5.1. Search Request
pub struct SearchRequest {
base_object: l::LdapDN,
scope: SearchRequestScope,
deref_aliases: SearchRequestDerefAliases,
size_limit: l::Integer,
time_limit: l::Integer,
types_only: bool,
filter: Filter,
attributes: AttributeSelection,
}
// 4.5.1.2. SearchRequest.scope
#[deriving(FromPrimitive)]
enum SearchRequestScope {
BaseObject = 0,
SingleLevel = 1,
WholeSubTree = 2,
}
// 4.5.1.3. SearchRequest.derefAliases
#[deriving(FromPrimitive)]
enum SearchRequestDerefAliases {
NeverDerefAliases = 0,
DerefInSearching = 1,
DerefFindingBaseObj = 2,
DerefAlways = 3,
}
// 4.5.1.7. SearchRequest.filter
enum Filter {
And(HashSet<Filter>),
Or(HashSet<Filter>),
Not(Box<Filter>),
EqualityMatch(l::AttributeValueAssertion),
Substrings(SubstringFilter),
GreaterOrEqual(l::AttributeValueAssertion),
LessOrEqual(l::AttributeValueAssertion),
Present(l::AttributeDescription),
ApproxMatch(l::AttributeValueAssertion),
ExtensibleMatch(MatchingRuleAssertion),
}
// 4.5.1.7.2. SearchRequest.filter.substrings
struct SubstringFilter {
ty: l::AttributeDescription,
substrings: Vec<Substring>
}
enum Substring {
Initial(l::AssertionValue),
Any(l::AssertionValue),
Final(l::AssertionValue),
}
// 4.5.1.7.7. SearchRequest.filter.extensibleMatch
struct MatchingRuleAssertion {
matching_rule: Option<l::MatchingRuleId>,
ty: Option<l::AttributeDescription>,
match_value: l::AssertionValue,
dn_attributes: bool,
}
// 4.5.1.8. SearchRequest.attributes
struct AttributeSelection(Vec<l::LdapString>);
// 4.5.2. Search Result
pub struct SearchResultEntry {
object_name: l::LdapDN,
attributes: PartialAttributeList,
}
struct PartialAttributeList(Vec<l::PartialAttribute>);
pub struct SearchResultReference(Vec<l::URI>);
pub struct SearchResultDone(l::LdapResult);
// 4.6. Modify Operation
pub struct ModifyRequest {
object: l::LdapDN,
changes: Vec<Change>,
}
struct Change {
operation: ChangeOperation,
modification: l::PartialAttribute,
}
#[deriving(FromPrimitive)]
enum ChangeOperation {
Add = 0,
Delete = 1,
Replace = 2,
}
pub struct ModifyResponse(l::LdapResult);
// 4.7. Add Operation
pub struct AddRequest {
entry: l::LdapDN,
attributes: AttributeList,
}
struct AttributeList(Vec<l::Attribute>);
pub struct AddResponse(l::LdapResult);
// 4.8. Delete Operation
pub struct DelRequest(l::LdapDN);
pub struct DelResponse(l::LdapResult);
// 4.9. Modify DN Operation
pub struct ModifyDNRequest {
entry: l::LdapDN,
newrdn: l::RelativeLdapDN,
deleteoldrdn: bool,
new_superior: Option<l::LdapDN>,
}
pub struct ModifyDNResponse(l::LdapResult);
// 4.10. Compare Operation
pub struct CompareRequest {
entry: l::LdapDN,
ava: l::AttributeValueAssertion,
}
pub struct CompareResponse(l::LdapResult);
// 4.11. Abandon Operation
pub struct AbandonRequest(l::MessageID);
// 4.12. Extended Operation
pub struct ExtendedRequest {
request_name: l::LdapOid,
request_value: Option<Vec<u8>>,
}
pub struct ExtendedResponse {
ldap_result: l::LdapResult,
response_name: Option<l::LdapOid>,
response_value: Option<Vec<u8>>,
}
// 4.13. Intermediate Response
pub struct IntermediateResponse {
response_name: Option<l::LdapOid>,
response_value: Option<Vec<u8>>,
}
// Appendix A. LDAP Result Codes
// A.2. Result Codes
#[deriving(FromPrimitive)]
pub enum LdapResultCode {
Success = 0,
OperationsError = 1,
ProtocoLError = 2,
TimeLimitExceeded = 3,
SizeLimitExceeded = 4,
CompareFalse = 5,
CompareTrue = 6,
AuthMethodNotSupported = 7,
StrongerAuthRequired = 8,
// 9 reserved
Referral = 10,
AdminLimitExceeded = 11,
UnavailableCriticalExtension = 12,
ConfidentialityRequired = 13,
SaslBindInProgress = 14,
NoSuchAttribute = 16,
UndefinedAttributeType = 17,
InappropriateMatching = 18,
ConstraintViolation = 19,
AttributeOrValueExists = 20,
InvalidAttributeSyntax = 21,
// 22-31 unused
NoSuchObject = 32,
AliasProblem = 33,
InvalidDNSSyntax = 34,
// 35 reserved for undefined isLeaf
AliasDereferencingProblem = 36,
// 37-47 unused
InappropriateAuthentication = 48,
InvalidCredentials = 49,
InsufficientAccessRights = 50,
Busy = 51,
Unvailable = 52,
UnwillingToPerform = 53,
LoopDetect = 54,
// 55-63 unused
NamingViolation = 64,
ObjectClassViolation = 65,
NotAllowedOnNonLeaf = 66,
NotAllowedOnRDN = 67,
EntryAlreadyExists = 68,
ObjectClassModsProhibited = 69,
// 70 reserved for CLDAP
AffectsMultipleDSAs = 71,
// 72-79 unused
Other = 80,
}
}
// 4.1. Common Elements
// 4.1.1. Message Envelope
pub struct LdapMessage {
message_id: MessageID,
protocol_op: LdapMessageProtocolOp,
controls: Controls,
}
enum LdapMessageProtocolOp {
BindRequest(p::BindRequest),
BindResponse(p::BindResponse),
UnbindRequest(p::UnbindRequest),
SearchRequest(p::SearchRequest),
SearchResEntry(p::SearchResultEntry),
SearchResDone(p::SearchResultDone),
SearchResRef(p::SearchResultReference),
ModifyRequest(p::ModifyRequest),
ModifyResponse(p::ModifyResponse),
AddRequest(p::AddRequest),
AddResponse(p::AddResponse),
DelRequest(p::DelRequest),
DelResponse(p::DelResponse),
ModDNRequest(p::ModifyDNRequest),
ModDNResponse(p::ModifyDNResponse),
CompareRequest(p::CompareRequest),
CompareResponse(p::CompareResponse),
AbandonRequest(p::AbandonRequest),
ExtendedReq(p::ExtendedRequest),
ExtendedResp(p::ExtendedResponse),
IntermediateResponse(p::IntermediateResponse),
}
type Integer = u32;
// 4.1.1.1. MessageID
struct MessageID(Integer);
// 4.1.2. String Types
type LdapString = String;
struct LdapOid(String);
// 4.1.3. Distinguished Name and Relative Distinguished Name
struct LdapDN(LdapString);
struct RelativeLdapDN(LdapString);
// 4.1.4. Attribute Descriptions
struct AttributeDescription(LdapString);
// 4.1.5. Attribute Value
struct AttributeValue(String);
// 4.1.6. Attribute Value Assertion
struct AttributeValueAssertion {
attribute_desc: AttributeDescription,
assertion_value: AssertionValue,
}
struct AssertionValue(Vec<u8>);
// 4.1.7. Attribute and PartialAttribute
struct PartialAttribute {
ty: AttributeDescription,
vals: HashSet<AttributeValue>,
}
struct Attribute(PartialAttribute);
// 4.1.8. Matching Rule Identifier
struct MatchingRuleId(LdapString);
// 4.1.9. LdapResult
struct LdapResult {
result_code: p::LdapResultCode,
matched_dn: LdapDN,
diagnostic_message: LdapString,
referral: Option<Referral>,
}
// 4.1.10. Referral
struct Referral(Vec<URI>);
struct URI(LdapString);
// 4.1.11. Controls
struct Controls(Vec<Control>);
struct Control {
control_type: LdapOid,
criticality: bool,
control_value: Option<Vec<u8>>,
}
}
fn main() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment