diff --git a/ast.ml b/ast.ml
index 193b24c..6a764c2 100644
--- a/ast.ml
+++ b/ast.ml
@@ -15,11 +15,6 @@ type t =
   | Binop of t * operator * t
   | If of t * t * t (* cond then else *)
   | Apply of t * t list (* function application *)
-  (* these will be seperated into external functions. *)
-  | Set_binop_pre of operator * t
-  | Get_binop_pre of operator
-  | Set_binop_aso of operator * string
-  | Get_binop_aso of operator
 
 and operator =
   | Add | Sub | Mul | Div (* arithmetics *)
@@ -89,16 +84,5 @@ let print ast =
       pr "(if"; f co; f th; f el; pr ")"
     | Apply (f, args) ->
       pr "("; aux f; List.iter (fun a -> pr " "; aux a) args; pr ")"
-
-    | Set_binop_pre (op, pre) ->
-      pr "(set_pre %s " (op_to_string op);
-      aux pre;
-      pr ")"
-    | Get_binop_pre op ->
-      pr "(get_pre %s)" (op_to_string op)
-    | Set_binop_aso (op, aso) ->
-      pr "(set_assoc %s %s)" (op_to_string op) aso
-    | Get_binop_aso op ->
-      pr "(get_pre %s)" (op_to_string op)
   in
   aux ast; pr "\n"
diff --git a/eval.ml b/eval.ml
index a6de723..74ede96 100644
--- a/eval.ml
+++ b/eval.ml
@@ -168,6 +168,42 @@ module External = struct
     | [v] -> raise @@ Type.Invalid (Value.typeof v)
     | _ -> invalid_arg "External.floatfun"
 
+  let symbol_to_op op =
+    op
+    |> String.to_seqi
+    |> Lex.find_token
+    |> Option.get
+    |> fst
+    |> Parser.token_to_op
+
+  let set_op_pre = function
+    | [Symbol op; Int l] ->
+      let op = symbol_to_op op in
+      Hashtbl.replace Parser.precedence op l;
+      Nop
+    | _ -> failwith "set_op_pre"
+
+  let get_op_pre = function
+    | [Symbol op] ->
+      let op = symbol_to_op op in
+      Int (Hashtbl.find Parser.precedence op)
+    | _ -> failwith "get_op_pre"
+
+  let set_op_assoc = function
+    | [Symbol op; String a] ->
+      let op = symbol_to_op op in
+      Hashtbl.replace Parser.oper_assoc op @@ Parser.assoc_of_string a;
+      Nop
+    | _ -> failwith "set_op_assoc"
+
+  let get_op_assoc = function
+    | [Symbol op] ->
+      let op = symbol_to_op op in
+      Hashtbl.find_opt Parser.oper_assoc op
+      |> Option.value ~default: Parser.Left_to_right
+      |> (fun a -> String (Parser.assoc_to_string a))
+    | _ -> failwith "get_op_assoc"
+
   let apply f args =
     let f = match f with
       | "sin" -> floatfun Float.sin
@@ -175,6 +211,10 @@ module External = struct
       | "tan" -> floatfun Float.tan
       | "deg" -> floatfun deg
       | "rad" -> floatfun rad
+      | "set_op_pre" -> set_op_pre
+      | "get_op_pre" -> get_op_pre
+      | "set_op_assoc" -> set_op_assoc
+      | "get_op_assoc" -> get_op_assoc
       | _ -> raise @@ Invalid f
     in
     f args
@@ -250,23 +290,6 @@ let rec eval env ast =
       end
     | Apply (v, args) -> apply v args env
 
-    | Set_binop_pre (op, l) ->
-      let l =
-        match aux l with
-        | Int n -> n
-        | v -> raise @@ Type.Invalid (Value.typeof v)
-      in
-      Hashtbl.replace Parser.precedence op l;
-      Nop
-    | Get_binop_pre op ->
-      Int (Hashtbl.find Parser.precedence op)
-    | Set_binop_aso (op, a) ->
-      Hashtbl.replace Parser.oper_assoc op @@ Parser.assoc_of_string a;
-      Nop
-    | Get_binop_aso op ->
-      (match Hashtbl.find_opt Parser.oper_assoc op with
-       | None -> String "left"
-       | Some a -> String (Parser.assoc_to_string a))
     | _ -> failwith "Eval.eval"
 
 (* apply args to result of expr *)
diff --git a/main.ml b/main.ml
index 2577d39..f3dd1ba 100644
--- a/main.ml
+++ b/main.ml
@@ -27,6 +27,8 @@ let print_error e =
 let stdlib = [
   "sin"; "cos"; "tan";
   "deg"; "rad";
+  "get_op_pre"; "set_op_pre";
+  "get_op_assoc"; "set_op_assoc";
 ]
   |> List.to_seq
   |> Seq.map (fun v -> v, External v)
diff --git a/parser.ml b/parser.ml
index d967970..8e06d4b 100644
--- a/parser.ml
+++ b/parser.ml
@@ -191,11 +191,9 @@ and expr pre seq =
   seq |> oneof [
     ifexpr;
     let_value;
-    oneof [apply; unary; value] @> binop pre;
-    level;
-    assoc;
     lambda;
     extern_value;
+    oneof [apply; unary; value] @> binop pre;
     (* TODO: place error routine here *)
   ]
 
@@ -209,32 +207,6 @@ and let_value seq =
   let f, seq = mustbe (expr min_int) seq in
   Letin (id, e, f), seq
 
-(* level := "level" {"get" | "set"} [op] *)
-and level seq =
-  let _, seq = ident "level" seq in
-  let id, seq = idents (S.of_list ["get"; "set"]) seq in
-  let op, seq = operator seq in
-  if id = "get" then
-    Get_binop_pre op, seq
-  else if id = "set" then
-    let v, seq = value seq in
-    Set_binop_pre (op, v), seq
-  else
-    failwith "Parser.level"
-
-(* assoc := "assoc" {"get" | "set"} [op] *)
-and assoc seq =
-  let _, seq = ident "assoc" seq in
-  let id, seq = idents (S.of_list ["get"; "set"]) seq in
-  let op, seq = operator seq in
-  if id = "get" then
-    Get_binop_aso op, seq
-  else if id = "set" then
-    let a, seq = idents (S.of_list ["left"; "right"]) seq in
-    Set_binop_aso (op, a), seq
-  else
-    failwith "Parser.assoc"
-
 (* lambda := "fun" [ident]+ "->" expr *)
 and lambda seq =
   let _, seq = ident "fun" seq in