theultraman20

Untitled

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