Initial work on function compilation

So far we only got constants and store-ptr.
Not supported by the frontend yet, so far only in tests.
pull/3/head
itycodes 2 weeks ago
parent 27d0e02b86
commit e33e43e221

@ -7,6 +7,8 @@ use std::fmt::Write;
use super::StorageClass;
use crate::parser::Ast;
#[derive(Debug, PartialEq, Clone)]
pub enum Type {
Pointer(Box<Type>, StorageClass),
@ -292,3 +294,116 @@ pub fn spirv_meta(module: Module) -> String {
}
spirv_asm
}
enum Number {
Int(i32),
Float(f32),
NotANumber,
}
fn match_number(s: &str) -> Number {
// floats have to be in the format of [0-9]+\.[0-9]*
// integers have to be in the format of [0-9]+
let mut chars = s.chars();
let mut has_dot = false;
while let Some(c) = chars.next() {
if c == '.' {
if has_dot {
// only one dot allowed.
return Number::NotANumber;
}
has_dot = true;
} else if !c.is_digit(10) {
// not a number;
// has a character that is not a digit or a dot.
return Number::NotANumber;
}
}
if has_dot {
// we have checked that the whole thing is numbers and dots
// and that there is precisely one dot
// that matches the regex.
Number::Float(s.parse().unwrap())
} else {
// this is an integer, since no dots.
Number::Int(s.parse().unwrap())
}
}
pub fn compile_ast_ssa(
ast: Ast,
vars: &mut Vec<(String, String)>,
mut constants: &mut Vec<(String, String)>,
mut counter: &mut Box<i32>,
mut stack: &mut Vec<String>,
mut out: &mut Vec<(Option<String>, String)>,
) {
match ast.clone().list() {
Some(l) => {
let mut lst = l.clone();
assert!(!lst.is_empty());
let fun = lst.remove(0);
assert!(true); // no safe remove, thanks Rust
let fun_name = fun.symbol();
assert!(fun_name.is_some());
let fun_name = fun_name.unwrap();
match fun_name.as_str() {
"store-ptr" => {
assert!(lst.len() == 2);
let ptr = lst.pop().unwrap();
let val = lst.pop().unwrap();
compile_ast_ssa(ptr, vars, constants, counter, stack, out);
compile_ast_ssa(val, vars, constants, counter, stack, out);
let val_id = stack.pop().unwrap();
let ptr_id = stack.pop().unwrap();
out.push((None, format!("OpStore {} {}", fix_name(&val_id), fix_name(&ptr_id))));
}
s => {
panic!("Unknown function: {} with params {:#?} in context:\n{:#?}", s, lst, ast);
}
}
}
None => {
let sym = ast.clone().symbol();
assert!(sym.is_some());
let sym = sym.unwrap();
match match_number(&sym) {
Number::Int(i) => {
let key = format!("i32_{}", i);
let mut contains = false;
for c in constants.iter() {
if c.0 == key {
contains = true;
}
}
if contains {
constants.push((key.clone(), format!("OpConstant %i32 {}", i.to_string())));
}
stack.push(key);
}
Number::Float(f) => {
let key = format!("f32_{}", f);
let mut contains = false;
for c in constants.iter() {
if c.0 == key {
contains = true;
}
}
if contains {
constants.push((key.clone(), format!("OpConstant %f32 {}", f.to_string())));
}
stack.push(key);
}
Number::NotANumber => {
for v in vars.iter() {
if v.0 == sym {
stack.push(v.0.clone());
return;
}
}
panic!("Unknown variable or constant: {}", sym);
}
}
}
}
}

Loading…
Cancel
Save