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