theultraman20

compile.rs

Jul 6th, 2024 (edited)
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.61 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: for<'a, 'b> fn(&'a mut Compiler<'b>),//Fn<&'a mut self>,
  19. infix: for<'a, 'b> fn(&'a mut Compiler<'b>),//Fn<&'a 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<'b>(&'b mut self) {
  100. self.parse_precedence(Assignemnt);
  101. }
  102.  
  103.  
  104. //prolly gonna have to change this later
  105. fn grouping<'b>(&'b 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<'b>(&'b 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<'b>(&'b 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<'b>(&'b mut self, token_type: TokenType) -> ParseRule {
  139. let null_fn = || {};
  140.  
  141. match token_type {
  142. LeftParen => ParseRule{ prefix: Compiler::<'b>::<'b>::grouping, infix: null_fn, prec: Null },
  143. Minus => ParseRule{ prefix: Compiler::<'b>::unary, infix: Compiler::<'b>::binary, prec: Term },
  144. Plus => ParseRule{ prefix: null_fn, infix: Compiler::<'b>::binary, prec: Term },
  145. Slash => ParseRule{ prefix: null_fn, infix: Compiler::<'b>::binary, prec: Factor },
  146. Star => ParseRule{ prefix: null_fn, infix: Compiler::<'b>::binary, prec: Factor },
  147. Number => ParseRule{ prefix: Compiler::<'b>::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