diff --git a/front/parser/src/ast.rs b/front/parser/src/ast.rs index 47a9bcf9..bac4578f 100644 --- a/front/parser/src/ast.rs +++ b/front/parser/src/ast.rs @@ -174,6 +174,7 @@ pub enum Operator { LogicalNot, BitwiseNot, Not, + Neg, } #[derive(Debug, Clone)] @@ -287,6 +288,20 @@ impl Expression { Expression::MethodCall { .. } => { panic!("nested method call type inference not supported yet") } + Expression::Unary { operator, expr } => { + let t = expr.get_wave_type(variables); + match operator { + Operator::Neg => { + match &t { + WaveType::Int(_) | WaveType::Uint(_) | WaveType::Float(_) => t, + _ => panic!("unary '-' not allowed for type {:?}", t), + } + } + Operator::Not | Operator::LogicalNot => WaveType::Bool, + Operator::BitwiseNot => t, + _ => panic!("unary op type inference not supported: {:?}", operator), + } + } _ => panic!("get_wave_type not implemented for {:?}", self), } } diff --git a/front/parser/src/expr/unary.rs b/front/parser/src/expr/unary.rs index 4bca96b1..25eeaff0 100644 --- a/front/parser/src/expr/unary.rs +++ b/front/parser/src/expr/unary.rs @@ -71,9 +71,12 @@ where Expression::Literal(Literal::Float(f)) => { return Some(Expression::Literal(Literal::Float(-f))); } - _ => { - println!("Error: unary '-' only supports numeric literals (line {})", tok.line); - return None; + + other => { + return Some(Expression::Unary { + operator: Operator::Neg, + expr: Box::new(other), + }) } } } diff --git a/front/parser/src/parser/stmt.rs b/front/parser/src/parser/stmt.rs index b3ae144a..012b1724 100644 --- a/front/parser/src/parser/stmt.rs +++ b/front/parser/src/parser/stmt.rs @@ -5,7 +5,7 @@ use lexer::token::TokenType; use crate::ast::{ASTNode, AssignOperator, Expression, Operator, StatementNode}; use crate::expr::{is_assignable, parse_expression, parse_expression_from_token}; use crate::parser::control::{parse_for, parse_if, parse_while}; -use crate::parser::decl::parse_var; +use crate::parser::decl::{parse_const, parse_let, parse_var}; use crate::parser::io::*; use crate::parser::types::is_expression_start; @@ -158,6 +158,14 @@ pub fn parse_statement(tokens: &mut Peekable>) -> Option { tokens.next(); parse_var(tokens) } + TokenType::Let => { + tokens.next(); + parse_let(tokens) + } + TokenType::Const => { + tokens.next(); + parse_const(tokens) + } TokenType::Println => { tokens.next(); parse_println(tokens) diff --git a/llvm_temporary/src/llvm_temporary/expression/rvalue/unary.rs b/llvm_temporary/src/llvm_temporary/expression/rvalue/unary.rs index 539eed22..c75830a0 100644 --- a/llvm_temporary/src/llvm_temporary/expression/rvalue/unary.rs +++ b/llvm_temporary/src/llvm_temporary/expression/rvalue/unary.rs @@ -11,6 +11,23 @@ pub(crate) fn gen<'ctx, 'a>( let val = env.gen(expr, None); match (operator, val) { + // - (negation) + (Operator::Neg, BasicValueEnum::IntValue(iv)) => { + let zero = iv.get_type().const_zero(); + env.builder + .build_int_sub(zero, iv, "neg") + .unwrap() + .as_basic_value_enum() + } + + (Operator::Neg, BasicValueEnum::FloatValue(fv)) => { + let zero = fv.get_type().const_float(0.0); + env.builder + .build_float_sub(zero, fv, "fneg") + .unwrap() + .as_basic_value_enum() + } + // ! (logical not) (Operator::LogicalNot, BasicValueEnum::IntValue(iv)) | (Operator::Not, BasicValueEnum::IntValue(iv)) => { @@ -33,4 +50,4 @@ pub(crate) fn gen<'ctx, 'a>( _ => panic!("Unsupported unary operator {:?} for value {:?}", operator, val), } -} +} \ No newline at end of file diff --git a/std/libc/c.wave b/std/libc/c.wave new file mode 100644 index 00000000..91eb43fb --- /dev/null +++ b/std/libc/c.wave @@ -0,0 +1,3 @@ +fun libc() { + 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."); +} \ No newline at end of file diff --git a/std/manifest.json b/std/manifest.json index 99c3c43c..f38e1903 100644 --- a/std/manifest.json +++ b/std/manifest.json @@ -1,5 +1,5 @@ { "name": "std", "format": 1, - "modules": ["string", "math"] + "modules": ["string", "math", "sys", "net", "libc"] } diff --git a/std/net/udp.wave b/std/net/udp.wave new file mode 100644 index 00000000..50b9096a --- /dev/null +++ b/std/net/udp.wave @@ -0,0 +1,8 @@ +import("../sys/linux/syscall"); + +const AF_INET: i64 = 2; +const SOCK_DGRAM: i64 = 2; + +fun udp_socket() -> i64 { + return sys_socket(AF_INET, SOCK_DGRAM, 0); +} diff --git a/std/sys/linux/syscall.wave b/std/sys/linux/syscall.wave new file mode 100644 index 00000000..5024f47b --- /dev/null +++ b/std/sys/linux/syscall.wave @@ -0,0 +1,14 @@ +const SYS_SOCKET: i64 = 41; + +fun sys_socket(domain: i64, ty: i64, proto: i64) -> i64 { + let fd: i64; + asm { + "syscall" + in("rax") SYS_SOCKET + in("rdi") domain + in("rsi") ty + in("rdx") proto + out("rax") fd + } + return fd; +}