float literals
This commit is contained in:
@@ -148,6 +148,12 @@ _builtin_cvttsd2si:
|
||||
cvttsd2si rax, xmm0
|
||||
ret
|
||||
|
||||
section .text._builtin_f64_to_float
|
||||
_builtin_f64_to_float:
|
||||
cvtsd2ss xmm0, xmm0
|
||||
movd eax, xmm0
|
||||
ret
|
||||
|
||||
section .text._builtin_syscall
|
||||
_builtin_syscall:
|
||||
mov rax, rdi
|
||||
@@ -603,6 +609,13 @@ _builtin_environ:
|
||||
TokenType::IntLiteral => {
|
||||
emit!(&mut self.output, " mov rax, {}", token.lexeme);
|
||||
}
|
||||
TokenType::FloatLiteral => {
|
||||
emit!(
|
||||
&mut self.output,
|
||||
" mov rax, __float64__({})",
|
||||
token.lexeme
|
||||
);
|
||||
}
|
||||
TokenType::CharLiteral => {
|
||||
emit!(
|
||||
&mut self.output,
|
||||
@@ -639,8 +652,13 @@ _builtin_environ:
|
||||
self.compile_expr(env, right)?;
|
||||
match op.token_type {
|
||||
TokenType::Minus => {
|
||||
if self.expr_types[&right.id] == "f64" {
|
||||
emit!(&mut self.output, " mov rbx, 0x8000000000000000");
|
||||
emit!(&mut self.output, " xor rax, rbx");
|
||||
} else {
|
||||
emit!(&mut self.output, " neg rax");
|
||||
}
|
||||
}
|
||||
TokenType::Bang => {
|
||||
emit!(&mut self.output, " test rax, rax");
|
||||
emit!(&mut self.output, " sete al");
|
||||
|
||||
@@ -675,6 +675,7 @@ impl Parser {
|
||||
fn primary(&mut self) -> Result<Expr, ZernError> {
|
||||
if self.match_token(&[
|
||||
TokenType::IntLiteral,
|
||||
TokenType::FloatLiteral,
|
||||
TokenType::CharLiteral,
|
||||
TokenType::StringLiteral,
|
||||
TokenType::True,
|
||||
|
||||
@@ -53,6 +53,10 @@ 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_syscall".into(), FnType::new_variadic("i64")),
|
||||
("_builtin_environ".into(), FnType::new("ptr", vec![])),
|
||||
("_var_arg".into(), FnType::new("any", vec!["i64"])),
|
||||
|
||||
@@ -39,6 +39,7 @@ pub enum TokenType {
|
||||
StringLiteral,
|
||||
CharLiteral,
|
||||
IntLiteral,
|
||||
FloatLiteral,
|
||||
True,
|
||||
False,
|
||||
|
||||
@@ -338,6 +339,8 @@ impl Tokenizer {
|
||||
}
|
||||
|
||||
fn scan_number(&mut self) -> Result<(), ZernError> {
|
||||
let mut is_float = false;
|
||||
|
||||
if self.match_char('x') {
|
||||
while self.peek().is_ascii_hexdigit() {
|
||||
self.advance();
|
||||
@@ -350,10 +353,24 @@ impl Tokenizer {
|
||||
while self.peek().is_ascii_digit() {
|
||||
self.advance();
|
||||
}
|
||||
if self.current + 1 < self.source.len()
|
||||
&& self.peek() == '.'
|
||||
&& self.source[self.current + 1] != '.'
|
||||
{
|
||||
is_float = true;
|
||||
self.advance();
|
||||
while self.peek().is_ascii_digit() {
|
||||
self.advance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if is_float {
|
||||
self.add_token(TokenType::FloatLiteral)
|
||||
} else {
|
||||
self.add_token(TokenType::IntLiteral)
|
||||
}
|
||||
}
|
||||
|
||||
fn scan_identifier(&mut self) -> Result<(), ZernError> {
|
||||
while self.peek().is_alphanumeric() || self.peek() == '_' || self.peek() == '.' {
|
||||
|
||||
@@ -429,6 +429,7 @@ impl<'a> TypeChecker<'a> {
|
||||
ExprKind::Grouping(expr) => self.typecheck_expr(env, expr),
|
||||
ExprKind::Literal(token) => match token.token_type {
|
||||
TokenType::IntLiteral => Ok("i64".into()),
|
||||
TokenType::FloatLiteral => Ok("f64".into()),
|
||||
TokenType::CharLiteral => Ok("u8".into()),
|
||||
TokenType::StringLiteral => Ok("str".into()),
|
||||
TokenType::True => Ok("bool".into()),
|
||||
@@ -439,8 +440,8 @@ impl<'a> TypeChecker<'a> {
|
||||
let right_type = self.typecheck_expr(env, right)?;
|
||||
match op.token_type {
|
||||
TokenType::Minus => {
|
||||
expect_type!(right_type, "i64", op.loc);
|
||||
Ok("i64".into())
|
||||
expect_types!(right_type, ["f64", "i64"], op.loc);
|
||||
Ok(right_type)
|
||||
}
|
||||
TokenType::Bang => {
|
||||
expect_types!(right_type, ["bool", "i64", "ptr", "u8"], op.loc);
|
||||
|
||||
Reference in New Issue
Block a user