Skip to content

Commit fd6934e

Browse files
authored
feat: support unary negation, let/const statements, and expand std syscalls (#271)
1 parent db13fc3 commit fd6934e

8 files changed

Lines changed: 74 additions & 6 deletions

File tree

front/parser/src/ast.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ pub enum Operator {
174174
LogicalNot,
175175
BitwiseNot,
176176
Not,
177+
Neg,
177178
}
178179

179180
#[derive(Debug, Clone)]
@@ -287,6 +288,20 @@ impl Expression {
287288
Expression::MethodCall { .. } => {
288289
panic!("nested method call type inference not supported yet")
289290
}
291+
Expression::Unary { operator, expr } => {
292+
let t = expr.get_wave_type(variables);
293+
match operator {
294+
Operator::Neg => {
295+
match &t {
296+
WaveType::Int(_) | WaveType::Uint(_) | WaveType::Float(_) => t,
297+
_ => panic!("unary '-' not allowed for type {:?}", t),
298+
}
299+
}
300+
Operator::Not | Operator::LogicalNot => WaveType::Bool,
301+
Operator::BitwiseNot => t,
302+
_ => panic!("unary op type inference not supported: {:?}", operator),
303+
}
304+
}
290305
_ => panic!("get_wave_type not implemented for {:?}", self),
291306
}
292307
}

front/parser/src/expr/unary.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,12 @@ where
7171
Expression::Literal(Literal::Float(f)) => {
7272
return Some(Expression::Literal(Literal::Float(-f)));
7373
}
74-
_ => {
75-
println!("Error: unary '-' only supports numeric literals (line {})", tok.line);
76-
return None;
74+
75+
other => {
76+
return Some(Expression::Unary {
77+
operator: Operator::Neg,
78+
expr: Box::new(other),
79+
})
7780
}
7881
}
7982
}

front/parser/src/parser/stmt.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use lexer::token::TokenType;
55
use crate::ast::{ASTNode, AssignOperator, Expression, Operator, StatementNode};
66
use crate::expr::{is_assignable, parse_expression, parse_expression_from_token};
77
use crate::parser::control::{parse_for, parse_if, parse_while};
8-
use crate::parser::decl::parse_var;
8+
use crate::parser::decl::{parse_const, parse_let, parse_var};
99
use crate::parser::io::*;
1010
use crate::parser::types::is_expression_start;
1111

@@ -158,6 +158,14 @@ pub fn parse_statement(tokens: &mut Peekable<Iter<Token>>) -> Option<ASTNode> {
158158
tokens.next();
159159
parse_var(tokens)
160160
}
161+
TokenType::Let => {
162+
tokens.next();
163+
parse_let(tokens)
164+
}
165+
TokenType::Const => {
166+
tokens.next();
167+
parse_const(tokens)
168+
}
161169
TokenType::Println => {
162170
tokens.next();
163171
parse_println(tokens)

llvm_temporary/src/llvm_temporary/expression/rvalue/unary.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,23 @@ pub(crate) fn gen<'ctx, 'a>(
1111
let val = env.gen(expr, None);
1212

1313
match (operator, val) {
14+
// - (negation)
15+
(Operator::Neg, BasicValueEnum::IntValue(iv)) => {
16+
let zero = iv.get_type().const_zero();
17+
env.builder
18+
.build_int_sub(zero, iv, "neg")
19+
.unwrap()
20+
.as_basic_value_enum()
21+
}
22+
23+
(Operator::Neg, BasicValueEnum::FloatValue(fv)) => {
24+
let zero = fv.get_type().const_float(0.0);
25+
env.builder
26+
.build_float_sub(zero, fv, "fneg")
27+
.unwrap()
28+
.as_basic_value_enum()
29+
}
30+
1431
// ! (logical not)
1532
(Operator::LogicalNot, BasicValueEnum::IntValue(iv))
1633
| (Operator::Not, BasicValueEnum::IntValue(iv)) => {
@@ -33,4 +50,4 @@ pub(crate) fn gen<'ctx, 'a>(
3350

3451
_ => panic!("Unsupported unary operator {:?} for value {:?}", operator, val),
3552
}
36-
}
53+
}

std/libc/c.wave

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fun libc() {
2+
println("The libc library is designed to take full advantage of the C ABI, and as part of the Wave standard library, FFI is used only here. In other words, to use the C ABI, use here.");
3+
}

std/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"name": "std",
33
"format": 1,
4-
"modules": ["string", "math"]
4+
"modules": ["string", "math", "sys", "net", "libc"]
55
}

std/net/udp.wave

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import("../sys/linux/syscall");
2+
3+
const AF_INET: i64 = 2;
4+
const SOCK_DGRAM: i64 = 2;
5+
6+
fun udp_socket() -> i64 {
7+
return sys_socket(AF_INET, SOCK_DGRAM, 0);
8+
}

std/sys/linux/syscall.wave

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const SYS_SOCKET: i64 = 41;
2+
3+
fun sys_socket(domain: i64, ty: i64, proto: i64) -> i64 {
4+
let fd: i64;
5+
asm {
6+
"syscall"
7+
in("rax") SYS_SOCKET
8+
in("rdi") domain
9+
in("rsi") ty
10+
in("rdx") proto
11+
out("rax") fd
12+
}
13+
return fd;
14+
}

0 commit comments

Comments
 (0)