-
Notifications
You must be signed in to change notification settings - Fork 26
Conversation
src/repl/helper.rs
Outdated
fn complete( | ||
&self, | ||
_line: &str, | ||
_pos: usize, | ||
_ctx: &Context<'_>, | ||
) -> Result<(usize, Vec<Pair>), ReadlineError> { | ||
Ok((0, vec![])) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to do lots of fancy things with tab-completion, but that's a larger project, no need for it in a first draft.
I'd actually like to evaluate things as expressions by default, not as declarations. This is how node behaves:
and also GHCI and python
You can parse things as expressions by creating a new Analyzer and calling |
But how should the result of the expression then be calculated? We do not have an interpreter, only a jit and I have no idea how we can get the result of the jitted code that gets executed. |
- Hide repl behind a feature gate - Create basic command module - Start repl automatically if no input is provided
- Move all methods from swcc module to a common module - Add swcci binary
src/bin/common/mod.rs
Outdated
pub(super) const USAGE: &str = "\ | ||
usage: swcc [--help | -h] [--version | -V] [--debug-ir] [--debug-ast] [--debug-lex] | ||
[--debug-hir] [--jit] [--no-link | -c] [--preprocess-only | -E] | ||
[-I <dir>] [-D <id[=val]>] [<file>]"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it makes sense to share this across both binaries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I realized that after I committed it 😅
It will be fixed asap.
- backtrace mod and ColorChoice are now in common mod - Add some first code checking stuff to repl execute_code
- entered expression is inserted in the return expression of the main function - result of the "program" is printed to stdout
@@ -1052,6 +1052,7 @@ impl PureAnalyzer { | |||
/// This returns an opaque index to the `Metadata`. | |||
fn declare(&mut self, mut decl: Variable, init: bool, location: Location) -> Symbol { | |||
if decl.id == "main".into() { | |||
println!("main: {:?}", decl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
println!("main: {:?}", decl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ups 😅
let expr = match analyze(code, Parser::expr, PureAnalyzer::expr) { | ||
Ok(mut expr) => { | ||
expr.ctype = types::Type::Int(true); | ||
expr | ||
} | ||
Err(err) => { | ||
println!("error: {}", err.data); | ||
return; | ||
} | ||
}; | ||
let function_type = types::FunctionType { | ||
return_type: Box::new(types::Type::Int(true)), | ||
params: vec![], | ||
varargs: false, | ||
}; | ||
let qualifiers = hir::Qualifiers { | ||
volatile: false, | ||
c_const: false, | ||
func: hir::FunctionQualifiers { | ||
inline: false, | ||
no_return: false, | ||
}, | ||
}; | ||
|
||
let main = hir::Variable { | ||
ctype: types::Type::Function(function_type), | ||
storage_class: data::StorageClass::Extern, | ||
qualifiers, | ||
id: saltwater::InternedStr::get_or_intern("main"), | ||
}; | ||
|
||
let span = expr.location; | ||
let stmt = span.with(hir::StmtType::Return(Some(expr))); | ||
let init = hir::Initializer::FunctionBody(vec![stmt]); | ||
let decl = hir::Declaration { | ||
symbol: main.insert(), | ||
init: Some(init), | ||
}; | ||
let (result, _warns) = ir::compile(module, vec![span.with(decl)], false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks useful on its own, can you make it a function in src/lib.rs
called eval()
that's implemented on JIT
?
ctype: types::Type::Function(function_type), | ||
storage_class: data::StorageClass::Extern, | ||
qualifiers, | ||
id: saltwater::InternedStr::get_or_intern("main"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id: saltwater::InternedStr::get_or_intern("main"), | |
id: "main".into(), |
let qualifiers = hir::Qualifiers { | ||
volatile: false, | ||
c_const: false, | ||
func: hir::FunctionQualifiers { | ||
inline: false, | ||
no_return: false, | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let qualifiers = hir::Qualifiers { | |
volatile: false, | |
c_const: false, | |
func: hir::FunctionQualifiers { | |
inline: false, | |
no_return: false, | |
}, | |
}; | |
let qualifiers = hir::Qualifiers::default(); |
let module = initialize_jit_module(); | ||
let expr = match analyze(code, Parser::expr, PureAnalyzer::expr) { | ||
Ok(mut expr) => { | ||
expr.ctype = types::Type::Int(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look right. What's this meant to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this crashes on strings:
>> "a"
The application panicked (crashed).
Message: verification error: - inst1 (return v0): arg 0 (v0) has type i64, must match function signature of i32
note: while compiling function u0:0() -> i32 system_v {
gv0 = symbol colocated u1:0
block0:
v0 = global_value.i64 gv0
return v0
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead you could use a function name other than main
and set the return type to the type of the expression. Then you decide how to display the result depending on the type. That would also fix the current bug where 'a'
is displayed as 99
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had this code there, because otherwise I got an error from cranelift that it expected an i32 but got i64.
verification error: - inst1 (return v0): arg 0 (v0) has type i64, must match function signature of i32
note: while compiling function u0:0() -> i32 system_v {
block0:
v0 = iconst.i64 1
return v0
}
if let Err(err) = result { | ||
println!("failed to compile: {}", err.data); | ||
return; | ||
} | ||
|
||
let module = result.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to avoid unwrap
if possible.
if let Err(err) = result { | |
println!("failed to compile: {}", err.data); | |
return; | |
} | |
let module = result.unwrap(); | |
let module = match result { | |
Err(err) => { | |
println!("failed to compile: {}", err.data); | |
return; | |
} | |
Ok(module) => module), | |
}; |
I will close this pull request and reopen one because I have lost the overview and am not really satisfied with this one. |
This PR will introduce a proper Repl using rustyline and the
jit
backend.My current plan is to have a buffer which holds the code.
Every line will be processed like this:
buffer
buffer
main
method, execute it and reset thebuffer
buffer
It's probably possible to not reset the
buffer
and just override themain
method in the existing program.I'n also thinking about making the
buffer
not a string, but a list of parsed statements.Resolves #372