diff --git a/forge-script-lang/src/parser/forge_grammar.lalrpop b/forge-script-lang/src/parser/forge_grammar.lalrpop
index 0d20fe9758741a8f785d38a5a383106d53ffd044..72b701614a56bf95a390657ac79cefd941c4948f 100644
--- a/forge-script-lang/src/parser/forge_grammar.lalrpop
+++ b/forge-script-lang/src/parser/forge_grammar.lalrpop
@@ -6,46 +6,19 @@ grammar<'a>;
 
 pub Program: Program = {
     <ExpressionList> => Program(<>),
-}
-
-ExpressionBlock: ExpressionList = {
-    "{" "}" => ExpressionList::empty(),
-    "{" <ExpressionList> "}" => <>,
-}
-
-ExpressionList: ExpressionList = {
-    <Expression> => ExpressionList::production(vec![<>]),
-    <mut list:ExpressionList> ";" <expr:Expression> => {
-        list.expressions.push(expr);
-        list
-    },
-    <mut opt:ExpressionList> ";" => {
-        opt.is_void = true;
-        opt
-    },
-}
-
-FunctionDeclParamList = CommaSeperatedList<FunctionDeclParam>;
-
-FunctionDeclParam: DeclareIdent = {
-    Identifier => DeclareIdent::WithoutValue(<>),
-    <id:Identifier> "=" <def:ValueExpression> => DeclareIdent::WithValue(Assignment {
-        ident: id,
-        value: Box::new(def),
-    }),
-}
+};
 
 ParameterList: Vec<ValueExpression> = {
     "(" <CommaSeperatedValueExpressionList> ")" => <>,
     "(" ")" => Vec::new(),
-}
+};
 
 CommaSeperatedValueExpressionList = CommaSeperatedList<ValueExpression>;
 
 pub Expression: Expression = {
     ValueExpression => Expression::Value(<>),
     VoidExpression => Expression::Void(<>),
-}
+};
 
 ValueExpression: ValueExpression = {
     FirstClassDeclareExpression => <>,
@@ -53,32 +26,34 @@ ValueExpression: ValueExpression = {
     "let" <id:Identifier> "=" <expr:FirstClassDeclareExpression> => DeclareIdent::WithValue(
         Assignment { ident: id, value :Box::new(expr) }
     ).into(),
-}
+};
 
 VoidExpression: VoidExpression = {
-    UnaryStatement => <>
-}
+    UnaryStatement => <>,
+    IOStatement => <>,
+    ConditionalLoop => <>.into(),
+};
 
 FirstClassDeclareExpression: ValueExpression = {
     BoolOrExpression => <>,
     DeclareFunction => <>.into(),
-}
+};
 
 BoolOrExpression: ValueExpression = {
     BoolAndExpression => <>,
     <lhs:BoolOrExpression> "||" <rhs:BoolAndExpression> => ValueExpression::bool_or(lhs, rhs),
-}
+};
 
 BoolAndExpression: ValueExpression = {
     EqualityExpression => <>,
     <lhs:BoolAndExpression> "&&" <rhs:EqualityExpression> => ValueExpression::bool_and(lhs, rhs),
-}
+};
 
 EqualityExpression: ValueExpression = {
     ComparisonExpression => <>,
     <lhs:EqualityExpression> "==" <rhs:ComparisonExpression> => ValueExpression::equals(lhs, rhs),
     <lhs:EqualityExpression> "!=" <rhs:ComparisonExpression> => ValueExpression::not_equals(lhs, rhs),
-}
+};
 
 ComparisonExpression: ValueExpression = {
     AdditiveExpression => <>,
@@ -86,32 +61,37 @@ ComparisonExpression: ValueExpression = {
     <lhs:ComparisonExpression> ">" <rhs:AdditiveExpression> => ValueExpression::greater_than(lhs, rhs),
     <lhs:ComparisonExpression> "<=" <rhs:AdditiveExpression> => ValueExpression::greater_than_equal(lhs, rhs),
     <lhs:ComparisonExpression> ">=" <rhs:AdditiveExpression> => ValueExpression::greater_than_equal(lhs, rhs),
-}
+};
 
 AdditiveExpression: ValueExpression = {
     MultiplicativeExpression => <>,
     <lhs:AdditiveExpression> "+" <rhs:MultiplicativeExpression> => ValueExpression::add(lhs, rhs),
     <lhs:AdditiveExpression> "-" <rhs:MultiplicativeExpression> => ValueExpression::sub(lhs, rhs),
-}
+};
 
 MultiplicativeExpression: ValueExpression = {
     UnaryExpression => <>,
     <lhs:MultiplicativeExpression> "*" <rhs:UnaryExpression> => ValueExpression::mul(lhs, rhs),
     <lhs:MultiplicativeExpression> "/" <rhs:UnaryExpression> => ValueExpression::div(lhs, rhs),
     <lhs:MultiplicativeExpression> "%" <rhs:UnaryExpression> => ValueExpression::modulo(lhs, rhs),
-}
+};
+
+IOStatement: VoidExpression = {
+    "import" "{"  <items:CommaSeperatedList<IdentifierNode>> "}" "from" <source:StringValue> => Import { items, source }.into(),
+    "export" "{"  <items:CommaSeperatedList<IdentifierNode>> "}" => Export { items }.into(),
+};
 
 UnaryStatement: VoidExpression = {
     "print" <FirstClassDeclareExpression> => Print { expr: Box::new(<>) }.into(),
     "return" <FirstClassDeclareExpression> => Return { expr: Box::new(<>) }.into(),
-}
+};
 
 UnaryExpression: ValueExpression = {
     IndexedExpression => <>,
     "typeof" <UnaryExpression> => TypeofValue(Box::new(<>)).into(),
     "!" <UnaryExpression> => ValueExpression::Unary { operand: Box::new(<>), operator: UnaryOp::Not },
     "-" <UnaryExpression> => ValueExpression::Unary { operand: Box::new(<>), operator: UnaryOp::Negate },
-}
+};
 
 IndexedExpression: ValueExpression = {
     CallExpression => <>,
@@ -119,19 +99,36 @@ IndexedExpression: ValueExpression = {
         initialiser: Box::new(init),
         path: acc,
     }.into(),
-}
+};
 
 CallExpression: ValueExpression = {
     BaseExpression => <>,
     FunctionCall => <>.into(),
-}
+};
 
 BaseExpression: ValueExpression = {
     Literal => <>.into(),
     Identifier => <>.into(),
     Conditional => <>,
     "(" <ValueExpression> ")" => GroupedExpression { inner: Box::new(<>) }.into(),
-}
+};
+
+ExpressionBlock: ExpressionList = {
+    "{" <ExpressionList> "}" => <>,
+    "{" "}" => ExpressionList::empty(),
+};
+
+ExpressionList: ExpressionList = {
+    <Expression> => ExpressionList::production(vec![<>]),
+    <mut list:ExpressionList> ";" <expr:Expression> => {
+        list.expressions.push(expr);
+        list
+    },
+    <mut opt:ExpressionList> ";" => {
+        opt.is_void = true;
+        opt
+    },
+};
 
 DeclareFunction: DeclareFunction = {
     "fn" <ident:Identifier> "(" <params:FunctionDeclParamList?> ")" <body:ExpressionBlock> => DeclareFunction {
@@ -139,7 +136,17 @@ DeclareFunction: DeclareFunction = {
         params: params.unwrap_or_default(),
         body,
     }
-}
+};
+
+FunctionDeclParamList = CommaSeperatedList<FunctionDeclParam>;
+
+FunctionDeclParam: DeclareIdent = {
+    Identifier => DeclareIdent::WithoutValue(<>),
+    <id:Identifier> "=" <def:ValueExpression> => DeclareIdent::WithValue(Assignment {
+        ident: id,
+        value: Box::new(def),
+    }),
+};
 
 AccessorChainAnyEnding: Vec<AccessorType> = {
     AccessorChainEndingWithProperty => <>,
@@ -148,7 +155,7 @@ AccessorChainAnyEnding: Vec<AccessorType> = {
         ls.push(AccessorType::FunctionCall(func));
         ls
     },
-}
+};
 
 AccessorChainEndingWithProperty: Vec<AccessorType> = {
     Identifier => vec![AccessorType::Identifier(<>)],
@@ -165,12 +172,12 @@ AccessorChainEndingWithProperty: Vec<AccessorType> = {
         first.push(AccessorType::Identifier(id));
         first
     },
-}
+};
 
 Conditional: ValueExpression = {
     GuardedBlockList => Conditional { blocks: <>, fallback: None }.into(),
     <ls:GuardedBlockList> "else" <fb:ExpressionBlock> => Conditional { blocks: ls, fallback: Some(fb) }.into(),
-}
+};
 
 GuardedBlockList: Vec<GuardedBlock> = {
     GuardedBlock => vec![<>],
@@ -178,24 +185,46 @@ GuardedBlockList: Vec<GuardedBlock> = {
         ls.push(gb);
         ls
     },
-}
+};
 
 GuardedBlock: GuardedBlock = {
     "if" <guard:ValueExpression> <block:ExpressionBlock> => GuardedBlock {
         guard: Box::new(guard),
         block,
     },
-}
+};
+
+ConditionalLoop: ConditionalLoop = {
+    "while" <guard: ValueExpression> <block:ExpressionBlock> => ConditionalLoop {
+        block: GuardedBlock {
+            guard: Box::new(guard),
+            block,
+        },
+        fallback: None,
+    },
+    "while" <guard: ValueExpression> <block:ExpressionBlock> "finally" <fallback:ExpressionBlock> => ConditionalLoop {
+        block: GuardedBlock {
+            guard: Box::new(guard),
+            block,
+        },
+        fallback: Some(fallback),
+    },
+};
 
 FunctionCall: FunctionCall = {
     <id:Identifier> <params:ParameterList> => FunctionCall {
         name: id,
         params,
     }
-}
+};
+
+IdentifierNode: IdentifierNode = {
+    Identifier => IdentifierNode::Direct(<>),
+    IdentifierAsAlias => IdentifierNode::Alias(<>),
+};
 
 IdentifierAsAlias: IdentifierAlias = {
-    <base:Identifier> "as" <alias:Identifier> => IdentifierAlias(base.0, alias.0),
+    <base:"identifier"> "as" <alias:"identifier"> => IdentifierAlias(base, alias),
 };
 
 Identifier: Identifier = {
@@ -222,7 +251,7 @@ CommaSeperatedList<Type>: Vec<Type> = {
         ls.push(ty);
         ls
     }
-}
+};
 
 extern {
     type Location = usize;
diff --git a/forge-script-lang/tests/cases/conditionals.fs b/forge-script-lang/tests/cases/conditionals.fs
index b43b7998414be1adbd0f8a465f993c0af97f5604..2a57b2f144bb1624e346ed65deecc71392a4bd30 100644
--- a/forge-script-lang/tests/cases/conditionals.fs
+++ b/forge-script-lang/tests/cases/conditionals.fs
@@ -1,5 +1,5 @@
-import { random_float, random_int, random_bool } from "@runtime:random"
-import { truncate } from "@runtime:maths"
+import { random_float, random_int, random_bool } from "@runtime:random";
+import { truncate } from "@runtime:maths";
 
 let var_a = random_int(0, 10) >= 5;
 let var_b = random_bool();
@@ -7,4 +7,12 @@ let my_var = if if 1 + 2 > 4 { var_a } else { var_b } {
     truncate(random_float() * 10)
 } else {
     random_int(100, 200)
+};
+
+export { my_var };
+
+while some_expression {
+    print "foo";
+} finally {
+    print "bar";
 };
\ No newline at end of file