add file index field to SourcePosition, some refactor, put coroutines in Box

master
Ondřej Hruška 3 years ago
parent daff23dd98
commit 9d4fef5222
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 64
      crsn/crsn-sexp/src/error.rs
  2. 6
      crsn/crsn-sexp/src/lib.rs
  3. 65
      crsn/crsn-sexp/src/position.rs
  4. 17
      crsn/crsn-sexp/src/test.rs
  5. 1
      crsn/src/runtime/program.rs
  6. 4
      crsn/src/runtime/run_thread.rs
  7. 8
      crsn/src/runtime/run_thread/state.rs

@ -1,5 +1,6 @@
use std::{cmp, fmt};
use std::fmt::{Formatter, Debug};
use std::{fmt};
use super::SourcePosition;
use position::get_line_and_column;
/// The representation of an s-expression parse error.
pub struct Error {
@ -9,38 +10,6 @@ pub struct Error {
pub pos: SourcePosition,
}
/// Position in the input string
#[derive(PartialEq, Clone, Default)]
pub struct SourcePosition {
/// The line number on which the error occurred.
pub line: u32,
/// The column number on which the error occurred.
pub column: u32,
/// The index in the given string which caused the error.
pub index: u32,
}
impl fmt::Display for SourcePosition {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}:{}", self.line, self.column)
}
}
impl Debug for SourcePosition {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if f.alternate() {
f.debug_struct("SourcePosition")
.field("line", &self.line)
.field("column", &self.column)
.field("index", &self.index)
.finish()
} else {
// shorter version
write!(f, "Pos({}:{})", self.line, self.column)
}
}
}
/// Since errors are the uncommon case, they're boxed. This keeps the size of
/// structs down, which helps performance in the common case.
///
@ -66,24 +35,6 @@ impl fmt::Debug for Error {
impl std::error::Error for Error {}
pub(crate) fn get_line_and_column(s: &str, pos: usize) -> SourcePosition {
let mut line: usize = 1;
let mut col: isize = -1;
for c in s.chars().take(pos + 1) {
if c == '\n' {
line += 1;
col = -1;
} else {
col += 1;
}
}
SourcePosition {
line: line as u32,
column: cmp::max(col, 0) as u32,
index: pos as u32,
}
}
#[cold]
fn err_impl(message: &'static str, s: &str, pos: usize) -> Err {
Box::new(Error {
@ -96,12 +47,3 @@ fn err_impl(message: &'static str, s: &str, pos: usize) -> Err {
pub(crate) fn err<T>(message: &'static str, s: &str, pos: usize) -> ERes<T> {
Err(err_impl(message, s, pos))
}
/// Build a span
pub(crate) fn spos(s: &str, pos: usize) -> SourcePosition {
if pos >= s.len() {
Default::default()
} else {
get_line_and_column(s, pos)
}
}

@ -8,14 +8,16 @@ use std::borrow::Cow;
use std::fmt;
use std::str::{self, FromStr};
use error::{ERes, err, spos};
use error::{ERes, err};
pub use error::Error;
pub use error::SourcePosition;
pub use position::SourcePosition;
use position::spos;
#[cfg(test)]
mod test;
mod error;
mod position;
/// A single data element in an s-expression. Floats are excluded to ensure
/// atoms may be used as keys in ordered and hashed data structures.

@ -0,0 +1,65 @@
use std::{fmt, cmp};
use std::fmt::{Formatter, Debug};
/// Position in the input string
#[derive(PartialEq, Clone, Default)]
pub struct SourcePosition {
/// The line number on which the error occurred.
pub line: u32,
/// The column number on which the error occurred.
pub column: u32,
/// The index in the given string which caused the error.
pub index: u32,
/// File index if there are multiple files
pub file: u32,
}
impl fmt::Display for SourcePosition {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}:{}", self.line, self.column)
}
}
impl Debug for SourcePosition {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if f.alternate() {
f.debug_struct("SourcePosition")
.field("line", &self.line)
.field("column", &self.column)
.field("index", &self.index)
.field("file", &self.file)
.finish()
} else {
// shorter version
write!(f, "Pos({}:{})", self.line, self.column)
}
}
}
pub(crate) fn get_line_and_column(s: &str, pos: usize) -> SourcePosition {
let mut line: usize = 1;
let mut col: isize = -1;
for c in s.chars().take(pos + 1) {
if c == '\n' {
line += 1;
col = -1;
} else {
col += 1;
}
}
SourcePosition {
line: line as u32,
column: cmp::max(col, 0) as u32,
index: pos as u32,
file: 0
}
}
/// Build a span
pub(crate) fn spos(s: &str, pos: usize) -> SourcePosition {
if pos >= s.len() {
Default::default()
} else {
get_line_and_column(s, pos)
}
}

@ -1,5 +1,6 @@
use super::*;
use super::error::get_line_and_column;
use super::position::get_line_and_column;
#[test]
fn test_hello_world() {
@ -67,16 +68,16 @@ fn show_an_error() {
#[test]
fn line_and_col_test() {
let s = "0123456789\n0123456789\n\n6";
assert_eq!(get_line_and_column(s, 4), SourcePosition { line: 1, column: 4, index: 4 });
assert_eq!(get_line_and_column(s, 4), SourcePosition { line: 1, column: 4, index: 4, file: 0 });
assert_eq!(get_line_and_column(s, 10), SourcePosition { line: 2, column: 0, index: 10 });
assert_eq!(get_line_and_column(s, 11), SourcePosition { line: 2, column: 0, index: 11 });
assert_eq!(get_line_and_column(s, 15), SourcePosition { line: 2, column: 4, index: 15 });
assert_eq!(get_line_and_column(s, 10), SourcePosition { line: 2, column: 0, index: 10, file: 0 });
assert_eq!(get_line_and_column(s, 11), SourcePosition { line: 2, column: 0, index: 11, file: 0 });
assert_eq!(get_line_and_column(s, 15), SourcePosition { line: 2, column: 4, index: 15, file: 0 });
assert_eq!(get_line_and_column(s, 21), SourcePosition { line: 3, column: 0, index: 21 });
assert_eq!(get_line_and_column(s, 22), SourcePosition { line: 4, column: 0, index: 22 });
assert_eq!(get_line_and_column(s, 23), SourcePosition { line: 4, column: 0, index: 23 });
assert_eq!(get_line_and_column(s, 500), SourcePosition { line: 4, column: 0, index: 500 });
assert_eq!(get_line_and_column(s, 21), SourcePosition { line: 3, column: 0, index: 21, file: 0 });
assert_eq!(get_line_and_column(s, 22), SourcePosition { line: 4, column: 0, index: 22, file: 0 });
assert_eq!(get_line_and_column(s, 23), SourcePosition { line: 4, column: 0, index: 23, file: 0 });
assert_eq!(get_line_and_column(s, 500), SourcePosition { line: 4, column: 0, index: 500, file: 0 });
}
#[test]

@ -100,6 +100,7 @@ impl Program {
line: 0,
column: 0,
index: 0,
file: 0,
},
cond: None,
}

@ -54,12 +54,12 @@ impl RunThread {
let rs = RunState {
thread_info: ti.clone(),
cr: CoroutineContext {
cr: Box::new(CoroutineContext {
handle: 0, // this is the root
frame: StackFrame::new(params.pc, params.args),
call_stack: vec![],
cr_state: Default::default(),
},
}),
parked: Default::default(),
global_regs: [0; REG_COUNT],
ext_data: Default::default(),

@ -17,9 +17,9 @@ use std::time::{Instant, Duration};
pub struct RunState {
pub thread_info: Arc<ThreadInfo>,
/// The active coroutine
pub cr: CoroutineContext,
pub cr: Box<CoroutineContext>,
/// Parked coroutines
pub parked: VecDeque<CoroutineContext>,
pub parked: VecDeque<Box<CoroutineContext>>,
/// General purpose registers that stay valid for the entire run-time of the thread
pub global_regs: [Value; REG_COUNT],
/// Extension data
@ -87,12 +87,12 @@ impl RunState {
trace!("Spawn cr {:#}", handle);
// front - so it runs ASAP
self.parked.push_front(CoroutineContext {
self.parked.push_front(Box::new(CoroutineContext {
handle,
frame,
call_stack: vec![],
cr_state: Default::default()
});
}));
if self.cr_deadline.is_none() {
// start context switching
self.start_task_switching();

Loading…
Cancel
Save