vinci/parser/instruction/
function.rs

1use crate::ast::instructions::function::{Call, Function};
2use crate::ast::instructions::Node;
3use crate::lexer::token::Token;
4use crate::parser::error::ParseError;
5use crate::parser::Parser;
6use crate::types::Type;
7
8/// ```
9/// use vinci::ast::AST;
10/// use vinci::ast::instructions::conditional::Conditional;
11/// use vinci::ast::instructions::function::Function;
12/// use vinci::ast::instructions::memory::{Load, LoadType};
13/// use vinci::ast::instructions::Node;
14/// use vinci::ast::instructions::suffix::{BinaryOperation, Suffix};
15/// use vinci::parse;
16/// use vinci::types::{Type, ValueType};
17/// let mut input = ".FUNCTION 0 INT ARGUMENTS {INT;} FREE { } THEN { .LOAD PARAMETER 0; };";
18/// let result = parse(input);
19///
20/// assert_eq!(result, AST {nodes: vec![
21///     Node::FUNCTION(
22///         Box::new(Function {
23///             index: 0,
24///             return_type: Type::INT,
25///             parameters: vec![Type::INT],
26///             body: vec![Node::LOAD(Load {
27///                 load_type: LoadType::PARAMETER,
28///                 index: 0
29///             })],
30///             free: vec![]
31///         })
32///     )]
33/// });
34/// ```
35pub fn parse_function_instruction(parser: &mut Parser) -> Result<Node, ParseError> {
36    let index;
37    let return_type;
38
39    if let Token::Number(idx) = parser.next_token() {
40        index = idx;
41    } else {
42        return Err(ParseError::UnexpectedToken(
43            Token::Type(Type::INT),
44            parser.current_token(),
45        ));
46    }
47
48    if let Token::Type(tp) = parser.next_token() {
49        return_type = tp;
50    } else {
51        return Err(ParseError::UnexpectedToken(
52            Token::Type(Type::INT),
53            parser.current_token(),
54        ));
55    }
56
57    parser.expected(Token::Arguments)?;
58
59    parser.expected(Token::LeftCurly)?;
60
61    let parameters: Vec<Type> = parse_type_arguments(parser)?;
62
63    parser.expected(Token::Free)?;
64    parser.expected(Token::LeftCurly)?;
65
66    let free: Vec<Type> = parse_type_arguments(parser)?;
67
68    parser.expected(Token::Then)?;
69
70    parser.expected(Token::LeftCurly)?;
71
72    let body = parser.parse_nodes()?;
73
74    parser.expected(Token::Semicolon)?;
75
76    Ok(Node::FUNCTION(Box::new(Function {
77        index: index as u32,
78        return_type,
79        parameters,
80        free,
81        body,
82    })))
83}
84
85/// ```
86/// use vinci::ast::AST;
87/// use vinci::ast::instructions::conditional::Conditional;
88/// use vinci::ast::instructions::function::{Call, Function};
89/// use vinci::ast::instructions::memory::{Load, LoadType};
90/// use vinci::ast::instructions::Node;
91/// use vinci::ast::instructions::suffix::{BinaryOperation, Suffix};
92/// use vinci::parse;
93/// use vinci::types::{Type, ValueType};
94/// let mut input = ".CALL local::0 { .CONSTANT INT 10; .CONSTANT INT 30; };";
95/// let result = parse(input);
96///
97/// assert_eq!(result, AST {nodes: vec![
98///     Node::CALL(Box::new(
99///         Call {
100///             namespace: "local::0".to_string(),
101///             arguments: vec![
102///                 Node::CONSTANT(ValueType::Integer(10)),
103///                 Node::CONSTANT(ValueType::Integer(30)),
104///             ]
105///         }
106///     ))]
107/// });
108/// ```
109pub fn parse_call_instruction(parser: &mut Parser) -> Result<Node, ParseError> {
110    let function_name;
111
112    if let Token::Namespace(ns) = parser.next_token() {
113        function_name = ns;
114    } else {
115        return Err(ParseError::UnexpectedToken(
116            Token::Namespace("namespace::function".to_string()),
117            parser.current_token(),
118        ));
119    }
120
121    parser.expected(Token::LeftCurly)?;
122
123    let arguments = parser.parse_nodes()?;
124
125    parser.expected(Token::Semicolon)?;
126
127    Ok(Node::CALL(Box::new(Call {
128        namespace: function_name,
129        arguments,
130    })))
131}
132
133fn parse_type_arguments(parser: &mut Parser) -> Result<Vec<Type>, ParseError> {
134    let mut parameters: Vec<Type> = Vec::new();
135    let mut next = parser.next_token();
136
137    while next != Token::RightCurly && next != Token::Error {
138        if let Token::Type(tp) = next {
139            parameters.push(tp);
140            parser.expected(Token::Semicolon)?;
141            next = parser.next_token();
142        } else {
143            break;
144        }
145    }
146
147    Ok(parameters)
148}