From 7b51c5c49fa676b64eaf927617c417c47f8863a1 Mon Sep 17 00:00:00 2001
From: JT <jonathan.d.turner@gmail.com>
Date: Thu, 8 Jul 2021 19:20:01 +1200
Subject: [PATCH] Add alias and external

---
 src/main.rs   | 10 ++++++++++
 src/parser.rs | 52 +++++++++++++++++++++++++++++++++------------------
 2 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 858431a69b..3e0f0c7292 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -32,6 +32,16 @@ fn main() -> std::io::Result<()> {
             );
         working_set.add_decl((b"let").to_vec(), sig);
 
+        let sig = Signature::build("alias")
+            .required("var_name", SyntaxShape::Variable, "variable name")
+            .required("=", SyntaxShape::Literal(b"=".to_vec()), "equals sign")
+            .required(
+                "value",
+                SyntaxShape::Expression,
+                "the value to set the variable to",
+            );
+        working_set.add_decl((b"alias").to_vec(), sig);
+
         //let file = std::fs::read(&path)?;
         //let (output, err) = working_set.parse_file(&path, file);
         let (output, err) = working_set.parse_source(path.as_bytes());
diff --git a/src/parser.rs b/src/parser.rs
index 45e6cdb4fb..b069fb2f3e 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -119,6 +119,7 @@ pub enum Expr {
     Int(i64),
     Var(VarId),
     Call(Box<Call>),
+    ExternalCall(Vec<u8>, Vec<Vec<u8>>),
     Operator(Operator),
     BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), //lhs, op, rhs
     Subexpression(Box<Block>),
@@ -300,7 +301,18 @@ fn span(spans: &[Span]) -> Span {
 impl ParserWorkingSet {
     pub fn parse_external_call(&mut self, spans: &[Span]) -> (Expression, Option<ParseError>) {
         // TODO: add external parsing
-        (Expression::garbage(spans[0]), None)
+        let mut args = vec![];
+        let name = self.get_span_contents(spans[0]).to_vec();
+        for span in &spans[1..] {
+            args.push(self.get_span_contents(*span).to_vec());
+        }
+        (
+            Expression {
+                expr: Expr::ExternalCall(name, args),
+                span: span(spans),
+            },
+            None,
+        )
     }
 
     pub fn parse_internal_call(
@@ -1143,24 +1155,28 @@ impl ParserWorkingSet {
     }
 
     pub fn parse_let(&mut self, spans: &[Span]) -> (Statement, Option<ParseError>) {
-        if let Some(decl_id) = self.find_decl(b"let") {
-            let (mut call, call_span, err) = self.parse_internal_call(spans, decl_id);
+        let name = self.get_span_contents(spans[0]);
 
-            if err.is_some() {
-                return (
-                    Statement::Expression(Expression {
-                        expr: Expr::Call(call),
-                        span: call_span,
-                    }),
-                    err,
-                );
-            } else if let Expression {
-                expr: Expr::Var(var_id),
-                ..
-            } = call.positional[0]
-            {
-                let expression = call.positional.swap_remove(2);
-                return (Statement::VarDecl(VarDecl { var_id, expression }), None);
+        if name == b"let" {
+            if let Some(decl_id) = self.find_decl(b"let") {
+                let (mut call, call_span, err) = self.parse_internal_call(spans, decl_id);
+
+                if err.is_some() {
+                    return (
+                        Statement::Expression(Expression {
+                            expr: Expr::Call(call),
+                            span: call_span,
+                        }),
+                        err,
+                    );
+                } else if let Expression {
+                    expr: Expr::Var(var_id),
+                    ..
+                } = call.positional[0]
+                {
+                    let expression = call.positional.swap_remove(2);
+                    return (Statement::VarDecl(VarDecl { var_id, expression }), None);
+                }
             }
         }
         (