Enable creating spaces

next
Sayan Nandan 2 years ago
parent 779fbb7785
commit 36a2b0162f
No known key found for this signature in database
GPG Key ID: 8BC07A0A4D41DD52

@ -76,6 +76,7 @@ impl Entity {
#[derive(Debug, PartialEq)]
pub enum Statement {
CreateModel(schema::Model),
CreateSpace(schema::Space),
}
pub struct Compiler<'a> {
@ -146,14 +147,19 @@ impl<'a> Compiler<'a> {
fn c_model0(&mut self) -> Result<Statement, LangError> {
let model_name = match self.nxtok_opt() {
Some(Token::Ident(model)) => unsafe { model.raw_clone() },
_ => return Err(LangError::UnexpectedEndofStatement),
_ => return Err(LangError::UnexpectedToken),
};
let model = schema::parse_schema(self, model_name)?;
Ok(Statement::CreateModel(model))
}
#[inline(always)]
fn c_space0(&mut self) -> Result<Statement, LangError> {
todo!()
let space_name = match self.nxtok_opt() {
Some(Token::Ident(space_name)) => unsafe { space_name.raw_clone() },
_ => return Err(LangError::UnexpectedToken),
};
let space = schema::parse_space(self, space_name)?;
Ok(Statement::CreateSpace(space))
}
}

@ -145,6 +145,12 @@ pub struct Model {
pub(super) props: Dict,
}
#[derive(Debug, PartialEq)]
pub struct Space {
pub(super) space_name: Box<str>,
pub(super) props: Dict,
}
/*
Context-free dict
*/
@ -269,33 +275,42 @@ pub struct TyMetaFoldResult {
}
impl TyMetaFoldResult {
#[inline(always)]
const fn new() -> Self {
Self {
c: 0,
b: [true, false],
}
}
#[inline(always)]
fn incr(&mut self) {
self.incr_by(1)
}
#[inline(always)]
fn incr_by(&mut self, by: usize) {
self.c += by;
}
#[inline(always)]
fn set_fail(&mut self) {
self.b[0] = false;
}
#[inline(always)]
fn set_has_more(&mut self) {
self.b[1] = true;
}
#[inline(always)]
pub fn pos(&self) -> usize {
self.c
}
#[inline(always)]
pub fn has_more(&self) -> bool {
self.b[1]
}
#[inline(always)]
pub fn is_okay(&self) -> bool {
self.b[0]
}
#[inline(always)]
fn record(&mut self, c: bool) {
self.b[0] &= c;
}
@ -631,20 +646,11 @@ pub(super) fn parse_schema_from_tokens(
}
// model properties
if i == l && okay {
// we've reached end of stream, so there's nothing more to parse
return Ok((
Model {
model_name,
props: dict! {},
fields,
},
i,
));
} else if !okay || tok[i] != Token::Keyword(Keyword::DdlMisc(DdlMiscKeyword::With)) {
if !okay {
return Err(LangError::UnexpectedToken);
}
if l > i && tok[i] == Token::Keyword(Keyword::DdlMisc(DdlMiscKeyword::With)) {
// we have some more input, and it should be a dict of properties
i += 1; // +WITH
@ -666,6 +672,17 @@ pub(super) fn parse_schema_from_tokens(
} else {
Err(LangError::UnexpectedToken)
}
} else {
// we've reached end of stream, so there's nothing more to parse
Ok((
Model {
model_name,
props: dict! {},
fields,
},
i,
))
}
}
pub(super) fn parse_schema(c: &mut Compiler, m: RawSlice) -> LangResult<Model> {
@ -678,3 +695,44 @@ pub(super) fn parse_schema(c: &mut Compiler, m: RawSlice) -> LangResult<Model> {
m
})
}
pub(super) fn parse_space_from_tokens(tok: &[Token], s: RawSlice) -> LangResult<(Space, usize)> {
let space_name = unsafe { s.as_str() }.into();
// let's see if the cursor is at `with`. ignore other tokens because that's fine
if !tok.is_empty() && tok[0] == Token::Keyword(Keyword::DdlMisc(DdlMiscKeyword::With)) {
// we have a dict
let mut d = Dict::new();
let ret = self::rfold_dict(DictFoldState::OB, &tok[1..], &mut d);
if ret & HIBIT == HIBIT {
Ok((
Space {
space_name,
props: d,
},
(ret & !HIBIT) as _,
))
} else {
Err(LangError::UnexpectedToken)
}
} else {
Ok((
Space {
space_name,
props: dict! {},
},
0,
))
}
}
pub(super) fn parse_space(c: &mut Compiler, s: RawSlice) -> LangResult<Space> {
self::parse_space_from_tokens(c.remslice(), s).map(|(m, i)| {
unsafe {
// UNSAFE(@ohsayan): The rfolds are very well tested to return the correct cursor position,
// so this should be completely safe
c.incr_cursor_by(i);
}
m
})
}

Loading…
Cancel
Save