split std
This commit is contained in:
@@ -147,8 +147,8 @@ _builtin_cvttsd2si:
|
||||
cvttsd2si rax, xmm0
|
||||
ret
|
||||
|
||||
.section .text._builtin_f64_to_float
|
||||
_builtin_f64_to_float:
|
||||
.section .text._builtin_f64_to_f32
|
||||
_builtin_f64_to_f32:
|
||||
cvtsd2ss xmm0, xmm0
|
||||
movd eax, xmm0
|
||||
ret
|
||||
@@ -648,10 +648,10 @@ _builtin_environ:
|
||||
|
||||
emit!(&mut self.output, " lea rax, [rip + {}]", label);
|
||||
}
|
||||
TokenType::True => {
|
||||
TokenType::KeywordTrue => {
|
||||
emit!(&mut self.output, " mov rax, 1");
|
||||
}
|
||||
TokenType::False => {
|
||||
TokenType::KeywordFalse => {
|
||||
emit!(&mut self.output, " mov rax, 0");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
||||
@@ -5,6 +5,7 @@ mod tokenizer;
|
||||
mod typechecker;
|
||||
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
fs,
|
||||
path::Path,
|
||||
process::{self, Command},
|
||||
@@ -27,8 +28,8 @@ fn compile_file(args: Args) -> Result<(), ZernError> {
|
||||
|
||||
let filename = Path::new(&args.path).file_name().unwrap().to_str().unwrap();
|
||||
|
||||
let mut tokenizer = tokenizer::Tokenizer::new(filename.to_owned(), source);
|
||||
tokenizer.include_file("std/std.zr".into())?;
|
||||
let mut included_paths = HashSet::new();
|
||||
let tokenizer = tokenizer::Tokenizer::new(filename.to_owned(), source, &mut included_paths);
|
||||
let parser = parser::Parser::new(tokenizer.tokenize()?);
|
||||
let statements = parser.parse()?;
|
||||
|
||||
|
||||
@@ -665,8 +665,8 @@ impl Parser {
|
||||
TokenType::FloatLiteral,
|
||||
TokenType::CharLiteral,
|
||||
TokenType::StringLiteral,
|
||||
TokenType::True,
|
||||
TokenType::False,
|
||||
TokenType::KeywordTrue,
|
||||
TokenType::KeywordFalse,
|
||||
]) {
|
||||
Ok(Expr::new(ExprKind::Literal(self.previous().clone())))
|
||||
} else if self.match_token(&[TokenType::LeftParen]) {
|
||||
|
||||
@@ -58,8 +58,8 @@ impl SymbolTable {
|
||||
("_builtin_cvtsi2sd".into(), FnType::new("f64", vec!["i64"])),
|
||||
("_builtin_cvttsd2si".into(), FnType::new("i64", vec!["f64"])),
|
||||
(
|
||||
"_builtin_f64_to_float".into(),
|
||||
FnType::new("i64", vec!["f64"]),
|
||||
"_builtin_f64_to_f32".into(),
|
||||
FnType::new("any", vec!["f64"]),
|
||||
),
|
||||
("_builtin_syscall".into(), FnType::new_variadic("i64")),
|
||||
("_builtin_environ".into(), FnType::new("ptr", vec![])),
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
use std::{cmp::Ordering, fmt, fs, path::Path};
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::HashSet,
|
||||
fmt, fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum TokenType {
|
||||
@@ -40,8 +45,6 @@ pub enum TokenType {
|
||||
CharLiteral,
|
||||
IntLiteral,
|
||||
FloatLiteral,
|
||||
True,
|
||||
False,
|
||||
|
||||
KeywordConst,
|
||||
KeywordIf,
|
||||
@@ -58,6 +61,8 @@ pub enum TokenType {
|
||||
KeywordStruct,
|
||||
KeywordNew,
|
||||
KeywordAs,
|
||||
KeywordTrue,
|
||||
KeywordFalse,
|
||||
|
||||
Indent,
|
||||
Dedent,
|
||||
@@ -109,7 +114,7 @@ pub struct Token {
|
||||
pub loc: Loc,
|
||||
}
|
||||
|
||||
pub struct Tokenizer {
|
||||
pub struct Tokenizer<'a> {
|
||||
source: Vec<char>,
|
||||
tokens: Vec<Token>,
|
||||
indent_stack: Vec<usize>,
|
||||
@@ -117,10 +122,15 @@ pub struct Tokenizer {
|
||||
start: usize,
|
||||
current: usize,
|
||||
loc: Loc,
|
||||
included_paths: &'a mut HashSet<PathBuf>,
|
||||
}
|
||||
|
||||
impl Tokenizer {
|
||||
pub fn new(filename: String, source: String) -> Tokenizer {
|
||||
impl<'a> Tokenizer<'a> {
|
||||
pub fn new(
|
||||
filename: String,
|
||||
source: String,
|
||||
included_paths: &'a mut HashSet<PathBuf>,
|
||||
) -> Tokenizer<'a> {
|
||||
Tokenizer {
|
||||
source: source.chars().collect(),
|
||||
tokens: vec![],
|
||||
@@ -133,6 +143,7 @@ impl Tokenizer {
|
||||
line: 1,
|
||||
column: 1,
|
||||
},
|
||||
included_paths,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,6 +368,9 @@ impl Tokenizer {
|
||||
self.advance();
|
||||
}
|
||||
} else {
|
||||
if self.source[self.current - 1] == '0' && self.peek().is_ascii_digit() {
|
||||
return error!(self.loc, "octal literals are not allowed");
|
||||
}
|
||||
while self.peek().is_ascii_digit() {
|
||||
self.advance();
|
||||
}
|
||||
@@ -406,8 +420,8 @@ impl Tokenizer {
|
||||
"struct" => TokenType::KeywordStruct,
|
||||
"new" => TokenType::KeywordNew,
|
||||
"as" => TokenType::KeywordAs,
|
||||
"true" => TokenType::True,
|
||||
"false" => TokenType::False,
|
||||
"true" => TokenType::KeywordTrue,
|
||||
"false" => TokenType::KeywordFalse,
|
||||
_ => TokenType::Identifier,
|
||||
})
|
||||
}
|
||||
@@ -437,8 +451,18 @@ impl Tokenizer {
|
||||
self.include_file(path)
|
||||
}
|
||||
|
||||
// TODO: circular includes lead to "fatal runtime error: stack overflow, aborting"
|
||||
pub fn include_file(&mut self, path: String) -> Result<(), ZernError> {
|
||||
fn include_file(&mut self, path: String) -> Result<(), ZernError> {
|
||||
let canonical = match fs::canonicalize(&path) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
return error!(self.loc, format!("failed to resolve {}: {}", path, e));
|
||||
}
|
||||
};
|
||||
|
||||
if !self.included_paths.insert(canonical) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let source = match fs::read_to_string(&path) {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
@@ -448,7 +472,7 @@ impl Tokenizer {
|
||||
|
||||
let filename = Path::new(&path).file_name().unwrap().to_str().unwrap();
|
||||
|
||||
let tokenizer = Tokenizer::new(filename.to_owned(), source);
|
||||
let tokenizer = Tokenizer::new(filename.to_owned(), source, &mut *self.included_paths);
|
||||
self.tokens.extend(tokenizer.tokenize()?);
|
||||
self.tokens.pop(); // remove inner Eof
|
||||
|
||||
|
||||
@@ -428,8 +428,8 @@ impl<'a> TypeChecker<'a> {
|
||||
TokenType::FloatLiteral => Ok("f64".into()),
|
||||
TokenType::CharLiteral => Ok("u8".into()),
|
||||
TokenType::StringLiteral => Ok("str".into()),
|
||||
TokenType::True => Ok("bool".into()),
|
||||
TokenType::False => Ok("bool".into()),
|
||||
TokenType::KeywordTrue => Ok("bool".into()),
|
||||
TokenType::KeywordFalse => Ok("bool".into()),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
ExprKind::Unary { op, right } => {
|
||||
|
||||
Reference in New Issue
Block a user