diff --git a/src/compiler/backend/mod.rs b/src/compiler/backend/mod.rs
index 53c59ac..d6ed454 100644
--- a/src/compiler/backend/mod.rs
+++ b/src/compiler/backend/mod.rs
@@ -145,6 +145,7 @@ fn fix_name(name: &String) -> String {
             .replace("-", "_")
             .replace("*", "p")
             .replace("<>", "void")
+            .replace(".", "_")
     )
 }
 
@@ -223,9 +224,26 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
             ],
         ));
     }
+    for global in module.globals.clone() {
+        let name: String = fix_name(&global.name);
+
+        for dec in global.decorations {
+            // Decorations have the format Location 0, or Builtin FragCoord
+            let dec = match dec {
+                crate::compiler::Decoration::Location(loc) => format!("Location {}", loc),
+                crate::compiler::Decoration::BuiltIn(builtin) => {
+                    let builtin = match builtin {
+                        crate::compiler::BuiltinDecoration::FragCoord => "FragCoord",
+                    };
+                    format!("BuiltIn {}", builtin)
+                }
+            };
+            ops.push((None, vec!["OpDecorate".to_string(), name.clone(), dec]));
+        }
+    }
 
     for global in module.globals.clone() {
-        let name = fix_name(&global.name);
+        let name: String = fix_name(&global.name);
         let _typ = global.typ;
         let storage_class = match global.storage_class {
             crate::compiler::StorageClass::Input => "Input",
@@ -248,19 +266,6 @@ pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
                 storage_class.to_string(),
             ],
         ));
-        for dec in global.decorations {
-            // Decorations have the format Location 0, or Builtin FragCoord
-            let dec = match dec {
-                crate::compiler::Decoration::Location(loc) => format!("Location {}", loc),
-                crate::compiler::Decoration::BuiltIn(builtin) => {
-                    let builtin = match builtin {
-                        crate::compiler::BuiltinDecoration::FragCoord => "FragCoord",
-                    };
-                    format!("BuiltIn {}", builtin)
-                }
-            };
-            ops.push((None, vec!["OpDecorate".to_string(), name.clone(), dec]));
-        }
     }
 
     for fun in module.functions.clone() {
@@ -337,6 +342,7 @@ fn compile_biop(
     counter: &mut i32,
     stack: &mut Vec<String>,
     out: &mut Vec<(Option<String>, String)>,
+    typ: &str,
 ) {
     assert!(lst.len() == 2);
     let rhs = lst.pop().unwrap();
@@ -352,7 +358,7 @@ fn compile_biop(
         format!(
             "{} {} {} {}",
             op,
-            fix_name(&String::from("f32")),
+            fix_name(&String::from(typ)),
             fix_name(&lhs_id),
             fix_name(&rhs_id),
         ),
@@ -360,6 +366,68 @@ fn compile_biop(
     stack.push(id);
 }
 
+fn compile_comp_constr(
+    lst: &mut Vec<Ast>,
+    vars: &mut Vec<(String, String)>,
+    constants: &mut Vec<(String, String)>,
+    types: &mut Vec<String>,
+    counter: &mut i32,
+    stack: &mut Vec<String>,
+    out: &mut Vec<(Option<String>, String)>,
+    typ: &str,
+) {
+    types.push(String::from(typ));
+    let typ_parsed = parse_type(&String::from(typ));
+    match typ_parsed {
+        Type::Vector(_, size) => {
+            assert!(lst.len() == size as usize);
+            let mut inners: Vec<String> = vec![];
+            for _ in 0..size {
+                let ast = lst.pop().unwrap();
+                compile_ast_ssa(ast, vars, constants, types, counter, stack, out);
+                let res_id = stack.pop().unwrap();
+                inners.push(res_id);
+            }
+            let id = String::from(counter.to_string());
+            *counter += 1;
+            let mut out_str = String::new();
+            out_str.push_str(
+                format!("OpCompositeConstruct {}", fix_name(&String::from(typ))).as_str(),
+            );
+            inners.reverse();
+            for inn in inners {
+                out_str.push_str(format!(" {}", fix_name(&inn)).as_str());
+            }
+            out.push((Some(id.clone()), out_str));
+            stack.push(id);
+        }
+        _ => {
+            panic!("Invalid vector!")
+        }
+    }
+}
+
+fn compile_comp_extract(    lst: &mut Vec<Ast>,
+    vars: &mut Vec<(String, String)>,
+    constants: &mut Vec<(String, String)>,
+    types: &mut Vec<String>,
+    counter: &mut i32,
+    stack: &mut Vec<String>,
+    out: &mut Vec<(Option<String>, String)>,
+    typ: &str, inx: u32) {
+    assert!(lst.len() == 1);
+    let vec = lst.pop().unwrap();
+    compile_ast_ssa(vec, vars, constants, types, counter, stack, out);
+    let vec_id = stack.pop().unwrap();
+    let id = counter.to_string();
+    *counter += 1;
+    out.push((
+        Some(id.clone()),
+        format!("OpCompositeExtract {} {} {}", fix_name(&String::from(typ)), fix_name(&vec_id), inx),
+    ));
+    stack.push(id);
+}
+
 pub fn compile_ast_ssa(
     ast: Ast,
     vars: &mut Vec<(String, String)>,
@@ -378,13 +446,82 @@ pub fn compile_ast_ssa(
             let fun_name = fun.symbol();
             assert!(fun_name.is_some());
             let fun_name = fun_name.unwrap();
+            if fun_name.starts_with(".") {
+                let to_split = &fun_name[1..fun_name.len()];
+                let split = to_split.split("-").collect::<Vec<&str>>();
+                assert!(split.len() == 2);
+                let inx = split[0];
+                let typ = split[1];
+                let inx = str::parse::<u32>(inx).expect("Invalid index!");
+                compile_comp_extract(&mut lst, vars, constants, types, counter, stack, out, typ, inx);
+                return;
+            }
+
+            if fun_name.starts_with("/") {
+                let typ = &fun_name[1..fun_name.len()];
+                compile_biop(
+                    "OpFDiv", &mut lst, vars, constants, types, counter, stack, out, typ,
+                );
+                return;
+            }
+
+
+            if fun_name.starts_with("*") {
+                let typ = &fun_name[1..fun_name.len()];
+                compile_biop(
+                    "OpFMul", &mut lst, vars, constants, types, counter, stack, out, typ,
+                );
+                return;
+            }
+
+
+            if fun_name.starts_with("+") {
+                let typ = &fun_name[1..fun_name.len()];
+                compile_biop(
+                    "OpFAdd", &mut lst, vars, constants, types, counter, stack, out, typ,
+                );
+                return;
+            }
+
+
+            if fun_name.starts_with("-") {
+                let typ = &fun_name[1..fun_name.len()];
+                compile_biop(
+                    "OpFSub", &mut lst, vars, constants, types, counter, stack, out, typ,
+                );
+                return;
+            }
+
+            if fun_name.starts_with("v") {
+                compile_comp_constr(
+                    &mut lst, vars, constants, types, counter, stack, out, fun_name.as_str(),
+                );
+                return;
+            }
+
+            if fun_name.starts_with("load-ptr-") {
+                let typ = &fun_name[9..fun_name.len()];
+                assert!(lst.len() == 1);
+                let ptr = lst.pop().unwrap();
+                compile_ast_ssa(ptr, vars, constants, types, counter, stack, out);
+                let ptr_id = stack.pop().unwrap();
+                let id: String = counter.to_string();
+                *counter += 1;
+                out.push((
+                    Some(id.clone()),
+                    format!("OpLoad {} {}", fix_name(&String::from(typ)), fix_name(&ptr_id)),
+                ));
+                stack.push(id);
+                return;
+            }
+
             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, types, counter, stack, out);
+                    let ptr = lst.pop().unwrap();
                     compile_ast_ssa(val, vars, constants, types, counter, stack, out);
+                    compile_ast_ssa(ptr, vars, constants, types, counter, stack, out);
                     let val_id = stack.pop().unwrap();
                     let ptr_id = stack.pop().unwrap();
                     out.push((
@@ -392,26 +529,6 @@ pub fn compile_ast_ssa(
                         format!("OpStore {} {}", fix_name(&val_id), fix_name(&ptr_id)),
                     ));
                 }
-                "/" => {
-                    compile_biop(
-                        "OpFDiv", &mut lst, vars, constants, types, counter, stack, out,
-                    );
-                }
-                "*" => {
-                    compile_biop(
-                        "OpFMul", &mut lst, vars, constants, types, counter, stack, out,
-                    );
-                }
-                "+" => {
-                    compile_biop(
-                        "OpFAdd", &mut lst, vars, constants, types, counter, stack, out,
-                    );
-                }
-                "-" => {
-                    compile_biop(
-                        "OpFSub", &mut lst, vars, constants, types, counter, stack, out,
-                    );
-                }
                 s => {
                     panic!(
                         "Unknown function: {} with params {:#?} in context:\n{:#?}",
@@ -534,6 +651,10 @@ pub fn compile_fun_ssa(module: &mut Module, ops: &Vec<(Option<String>, String)>)
                 out_ops.push((None, op.1));
             }
         }
+
+        out_ops.push((None, String::from("OpReturn")));
+        out_ops.push((None, String::from("OpFunctionEnd")));
+
         for op in out_ops {
             let split: Vec<String> = op.1.split(" ").map(|s| s.to_string()).collect();
             let op_name: String = (&split[0]).clone();
diff --git a/src/compiler/backend/tests.rs b/src/compiler/backend/tests.rs
index 6420b62..e4be473 100644
--- a/src/compiler/backend/tests.rs
+++ b/src/compiler/backend/tests.rs
@@ -63,7 +63,7 @@ fn test_block_ssa() {
 (dec out-color:*f32o Output)
 (entry main Fragment OriginUpperLeft (:out-color))
 (fun (main) :<>
-  (store-ptr out-color (/ 1.0 (+ 1.0 1.0))))
+  (store-ptr out-color (/f32 1.0 (+f32 1.0 1.0))))
 ";
     let ast = parse(tokenize(src));
     let mut module = meta_compile(ast.unwrap()).unwrap();
@@ -117,7 +117,7 @@ fn test_fun_ssa() {
         (dec out-color:*f32o Output)
         (entry main Fragment OriginUpperLeft (:out-color))
         (fun (main) :<>
-            (store-ptr out-color (/ 1.0 (+ 1.0 1.0))))
+            (store-ptr out-color (/f32 1.0 (+f32 1.0 1.0))))
 ";
     let ast = parse(tokenize(src));
     let mut module = meta_compile(ast.unwrap()).unwrap();
@@ -171,6 +171,40 @@ fn test_fun_ssa() {
             op: "OpStore".to_string(),
             operands: vec!["%out_color".to_string(), "%1".to_string()],
         },
+        Instruction {
+            result_id: None,
+            op: "OpReturn".to_string(),
+            operands: vec![]
+        },
+        Instruction {
+            result_id: None,
+            op: "OpFunctionEnd".to_string(),
+            operands: vec![]
+        }
     ];
     assert_eq!(res, res_spv);
 }
+
+#[test]
+fn test_fun_ssa_vec() {
+    use crate::compiler::backend::*;
+    use crate::compiler::*;
+    use crate::parser::*;
+    let src = "
+        (module Shader Logical GLSL450)
+        (import :std GLSL.std.450)
+        (bind (out-color:*v4f32o) (Location 0))
+        (dec out-color:*v4f32o Output)
+        (entry main Fragment OriginUpperLeft (:out-color))
+        (fun (main) :<>
+            (store-ptr out-color (v4f32 1.0 1.0 0.0 1.0)))
+";
+    let ast = parse(tokenize(src));
+    let mut module = meta_compile(ast.unwrap()).unwrap();
+    let ops = vec![];
+    compile_fun_ssa(&mut module, &ops);
+    let res = module.functions.pop().unwrap();
+    let res = res.body.unwrap();
+    println!("{:#?}", res);
+    println!("{:#?}", module)
+}
\ No newline at end of file