theultraman20

compile.rs

Jul 6th, 2024
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.09 KB | None | 0 0
  1.  
  2. use crate::Token;
  3. use crate::TokenType;
  4. use TokenType::*;
  5. use crate::vm::VmError;
  6. use crate::Op::*;
  7. use Precedence::*;
  8. use std::vec::IntoIter;
  9.  
  10. //only needs lifetime parameter because
  11. //token contains string slice
  12. struct Parser<'a> {
  13.    previous: Token<'a>,
  14.     current: Token<'a>,
  15. }
  16.  
  17. struct ParseRule {
  18.    prefix: Fn<&mut self>,
  19.    infix: Fn<&mut self>,
  20.    prec: Precedence,
  21. }
  22.  
  23. #[repr(u8)]
  24. enum Precedence {
  25.    Primary,
  26.    Call,       // . ()
  27.    Unary,      // !
  28.    Factor,     // * /
  29.    Term,       // + -
  30.    Comparison, // > < >= <=
  31.    Equality,
  32.    And,
  33.    Or,
  34.    Assignemnt,
  35.    Null,
  36. }
  37.  
  38. pub struct Compiler<'a> {
  39.     parser: Parser<'a>,
  40.    tokens: IntoIter<Token<'a>>,
  41.     bytecode: Vec<u8>,
  42.     const_pool: Vec<f64>,
  43. }
  44.  
  45. impl<'a> Compiler<'a> {
  46.  
  47.     pub fn new(tokens: Vec<Token<'a>>) -> Self {
  48.        Self {
  49.            tokens: tokens.into_iter(),
  50.            parser: Parser {
  51.                previous: Token {
  52.                    kind: Blank,
  53.                    line_num: 0,
  54.                    content: ""
  55.                },
  56.  
  57.                current: Token {
  58.                    kind: Blank,
  59.                    line_num: 0,
  60.                    content: ""
  61.                }
  62.            },
  63.            const_pool: vec![],
  64.            bytecode: vec![],
  65.        }
  66.    }
  67.  
  68.    //just implement the authors way, and change later
  69.    pub fn compile(&mut self) -> Result<Vec<u8>, VmError> {
  70.        
  71.        while let Some(token) = self.tokens.next() {
  72.            self.parser.previous = self.parser.current;
  73.            self.parser.current = token;
  74.  
  75.            match token.kind {
  76.                Number => {
  77.                    self.number();
  78.                },
  79.  
  80.                LeftParen => {
  81.                    //expression() is probably just compile()
  82.                    self.grouping();
  83.                },
  84.  
  85.                _ => todo!()
  86.            };
  87.        }
  88.  
  89.        //FIND way to clone without copying when you're not tired
  90.         Ok(std::mem::take(&mut self.bytecode))
  91.     }
  92.  
  93.     fn expression(&mut self) {
  94.         parse_precedence(Assignemnt);
  95.     }
  96.  
  97.  
  98.     //prolly gonna have to change this later
  99.     fn grouping(&mut self) {
  100.         //Never be afraid to express yourself :)
  101.         self.expression();
  102.         if self.tokens.next().map(|token| token.kind) != Some(RightParen) { panic!("Expected ')'"); }
  103.     }
  104.  
  105.     fn number(&mut self) {
  106.         let val = self.parser.current.content.parse::<f64>().unwrap();
  107.         self.const_pool.push(val);
  108.         if self.const_pool.len() > 256 { panic!("No room in const pool"); }
  109.  
  110.         self.bytecode.push(OpConstant as u8);
  111.         self.bytecode.push((self.const_pool.len()-1) as u8);
  112.     }
  113.  
  114.     //keep for now, possibly remove later
  115.     fn unary(&mut self) {
  116.         let op = self.parser.previous.kind;
  117.         self.expression();
  118.  
  119.         match op {
  120.             Minus => {
  121.                 self.bytecode.push(OpNegate as u8);
  122.             },
  123.             _ => unreachable!(),
  124.         };
  125.     }
  126.  
  127.     //What the fuck
  128.     fn parse_precedence(&mut self, level: Precedence) {
  129.  
  130.     }
  131.  
  132.     fn get_rule(&mut self, token_type: TokenType) -> ParseRule {
  133.         let null_fn = || {};
  134.  
  135.         match token_type {
  136.             LeftParen => ParseRule{ self.grouping, null_fn, Null },
  137.             Minus =>     ParseRule{ self.unary, self.binary, Term },
  138.             Plus =>      ParseRule{ null_fn, self.binary, Term },
  139.             Slash =>     ParseRule{ null_fn, self.binary, Factor },
  140.             Star =>      ParseRule{ null_fn, self.binary, Factor },
  141.             Number =>    ParseRule{ self.number, null_fn, Null },
  142.             _ =>         ParseRule{ null_fn, null_fn, Null },
  143.         }
  144.     }
  145.  
  146. }
  147.  
  148.  
  149.  
  150. /*
  151. Lox book C code reference:
  152.  
  153. bool compile(const char* source, Chunk* chunk) {
  154.     initScanner(source);
  155.     advance();
  156.     expression();
  157.     consume(TOKEN_EOF, "Expect end of expression.");
  158. }
  159.  
  160. //is this handled automatically in loop?
  161. void initScanner(const char* source) {
  162.     scanner.start = source;
  163.     scanner.current = source;
  164.     scanner.line = 1;
  165. }
  166.  
  167.  
  168. static void advance() {
  169.     parser.previous = parser.current;
  170.     parser.current = scanToken();
  171. }
  172.  
  173.  
  174. //scanner is for scanning TEXT, not tokens
  175. //handle with for loop
  176. Token scanToken() {
  177.     scanner.start = scanner.current;
  178.  
  179.     if (isAtEnd()) return makeToken(TOKEN_EOF);
  180.  
  181.     return errorToken("Unexpected character.");
  182. }
  183.  
  184. static void consume(TokenType type, const char* message) {
  185.     if (parser.current.type == type) {
  186.         advance();
  187.         return;
  188.     }
  189.  
  190.     errorAtCurrent(message);
  191. }
  192.  
  193. static void number() {
  194.     double value = strtod(parser.previous.start, NULL);
  195.     emitConstant(value);
  196. }
  197.  
  198. static void unary() {
  199.     TokenType operatorType = parser.previous.type;
  200.  
  201.     // Compile the operand.
  202.      expression();
  203.  
  204.      // Emit the operator instruction.
  205.     switch (operatorType) {
  206.         case TOKEN_MINUS: emitByte(OP_NEGATE); break;
  207.         default: return; // Unreachable.
  208.     }
  209. }
  210.  
  211. static void parsePrecedence(Precedence precedence) {
  212.   // What goes here?
  213. }
  214. */
  215.  
Add Comment
Please, Sign In to add comment