From 901af25b88e6140c5025e11f8226c58dc9b9cae8 Mon Sep 17 00:00:00 2001 From: Luuk Verweij Date: Wed, 13 Sep 2023 19:32:29 +0200 Subject: [PATCH] add zip example --- aaa-stdlib/src/stack.rs | 5 +- aaa-stdlib/src/vector.rs | 26 ++++++++- aaa/cross_referencer/cross_referencer.py | 16 +++--- aaa/cross_referencer/models.py | 4 ++ aaa/parser/single_file_parser.py | 1 - aaa/transpiler/transpiler.py | 28 +++++++--- zip.aaa | 67 ++++++++++++++++++++++++ 7 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 zip.aaa diff --git a/aaa-stdlib/src/stack.rs b/aaa-stdlib/src/stack.rs index 2099c59a..1d11914b 100644 --- a/aaa-stdlib/src/stack.rs +++ b/aaa-stdlib/src/stack.rs @@ -229,13 +229,14 @@ where } } - pub fn pop_vector_iterator(&mut self) -> Rc>>> { + pub fn pop_vec_iter(&mut self) -> Rc>>> { match self.pop() { Variable::VectorIterator(v) => v, v => self.pop_type_error("vec_iter", &v), } } + // TODO rename this and other similar functions like pop_vec_iter() pub fn pop_map_iterator(&mut self) -> Rc, Variable>>> { match self.pop() { Variable::MapIterator(v) => v, @@ -1197,7 +1198,7 @@ where } pub fn vec_iter_next(&mut self) { - let vector_iter_rc = self.pop_vector_iterator(); + let vector_iter_rc = self.pop_vec_iter(); let mut vector_iter = vector_iter_rc.borrow_mut(); match vector_iter.next() { diff --git a/aaa-stdlib/src/vector.rs b/aaa-stdlib/src/vector.rs index 03a45b65..b3aacd69 100644 --- a/aaa-stdlib/src/vector.rs +++ b/aaa-stdlib/src/vector.rs @@ -152,7 +152,7 @@ impl VectorIterator where T: UserType, { - fn new(vector: Rc>>, iterator_count: Rc>) -> Self { + pub fn new(vector: Rc>>, iterator_count: Rc>) -> Self { *iterator_count.borrow_mut() += 1; Self { @@ -161,6 +161,10 @@ where offset: 0, } } + + pub fn clone_recursive(&self) -> Self { + unreachable!() // TODO + } } impl Iterator for VectorIterator @@ -186,3 +190,23 @@ where *self.iterator_count.borrow_mut() -= 1; } } + +impl Display for VectorIterator +where + T: UserType, +{ + fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + unreachable!() // TODO + } +} + +impl PartialEq for VectorIterator +where + T: UserType, +{ + fn eq(&self, _other: &Self) -> bool { + unreachable!() // TODO + } +} + +impl Eq for VectorIterator where T: UserType {} diff --git a/aaa/cross_referencer/cross_referencer.py b/aaa/cross_referencer/cross_referencer.py index b9c82c10..e0144732 100644 --- a/aaa/cross_referencer/cross_referencer.py +++ b/aaa/cross_referencer/cross_referencer.py @@ -489,18 +489,20 @@ def _resolve_struct_field( is_const=parsed_field_type.const, ) - def _resolve_struct(self, struct: Struct) -> None: + def _resolve_struct_fields( + self, struct: Struct, params: Dict[str, Struct] + ) -> Dict[str, VariableType | FunctionPointer]: parsed_field_types = struct.get_unresolved().parsed_field_types - resolved_params = self._resolve_struct_params(struct) - fields = { - field_name: self._resolve_struct_field( - struct, resolved_params, parsed_field - ) + return { + field_name: self._resolve_struct_field(struct, params, parsed_field) for field_name, parsed_field in parsed_field_types.items() } - struct.resolve(resolved_params, fields) + def _resolve_struct(self, struct: Struct) -> None: + params = self._resolve_struct_params(struct) + fields = self._resolve_struct_fields(struct, params) + struct.resolve(params, fields) def _resolve_enum(self, enum: Enum) -> None: parsed_variants = enum.get_unresolved().parsed_variants diff --git a/aaa/cross_referencer/models.py b/aaa/cross_referencer/models.py index 7fbafc41..e06a3d0c 100644 --- a/aaa/cross_referencer/models.py +++ b/aaa/cross_referencer/models.py @@ -28,6 +28,10 @@ class Function(AaaCrossReferenceModel): class Unresolved: def __init__(self, parsed: parser.Function) -> None: self.parsed = parsed + self.type_params = { + type_param.identifier.name: type_param + for type_param in parsed.type_params + } self.type_params = { param.identifier.name: param for param in parsed.type_params diff --git a/aaa/parser/single_file_parser.py b/aaa/parser/single_file_parser.py index 4fb383a5..4f93a440 100644 --- a/aaa/parser/single_file_parser.py +++ b/aaa/parser/single_file_parser.py @@ -495,7 +495,6 @@ def _parse_struct_fields( def _parse_struct_declaration(self, offset: int) -> Tuple[Struct, int]: start_offset = offset - struct_token, offset = self._parse_token(offset, [TokenType.STRUCT]) type_literal, offset = self._parse_flat_type_literal(offset) diff --git a/aaa/transpiler/transpiler.py b/aaa/transpiler/transpiler.py index 4f4e7abc..422e7691 100644 --- a/aaa/transpiler/transpiler.py +++ b/aaa/transpiler/transpiler.py @@ -1,7 +1,7 @@ from datetime import datetime from hashlib import sha256 from pathlib import Path -from typing import Callable, Dict, List, Optional, Tuple, Type +from typing import Callable, Dict, List, Optional, Set, Tuple, Type from aaa import Position, create_output_folder from aaa.cross_referencer.models import ( @@ -101,17 +101,22 @@ def __init__( self.structs: Dict[Tuple[Path, str], Struct] = {} self.enums: Dict[Tuple[Path, str], Enum] = {} + self.builtin_type_names: Set[str] = set() # Function currently being transpiled self.current_function: Optional[Function] = None for key, struct in cross_referencer_output.structs.items(): - if struct.position.file != self.builtins_path: + if struct.position.file == self.builtins_path: + self.builtin_type_names.add(struct.name) + else: self.structs[key] = struct - for key, type in cross_referencer_output.enums.items(): - if type.position.file != self.builtins_path: - self.enums[key] = type + for key, enum in cross_referencer_output.enums.items(): + if enum.position.file == self.builtins_path: + self.builtin_type_names.add(enum.name) + else: + self.enums[key] = enum def run(self) -> None: generated_rust_file = self.transpiler_root / "src/main.rs" @@ -194,7 +199,7 @@ def _generate_imports(self) -> Code: code.add("use aaa_stdlib::stack::Stack;") code.add("use aaa_stdlib::set::{Set, SetValue};") code.add("use aaa_stdlib::var::{UserType, Variable};") - code.add("use aaa_stdlib::vector::Vector;") + code.add("use aaa_stdlib::vector::{Vector, VectorIterator};") code.add("use regex::Regex;") code.add("use std::cell::RefCell;") code.add("use std::collections::HashMap;") @@ -1123,6 +1128,12 @@ def _generate_struct_field_type(self, type: VariableType | FunctionPointer) -> s return "Rc>>>" elif type.name == "regex": return "Rc>" + elif type.name == "vec_iter": + return "Rc>>>" + + if type.name in self.builtin_type_names: + raise NotImplementedError # TODO + return "Rc>" def _generate_struct_impl(self, struct: Struct) -> Code: @@ -1160,7 +1171,12 @@ def _generate_struct_impl(self, struct: Struct) -> Code: code.add(f"{field_name}: Variable::map_zero_value(),") elif field_var_type.type.name == "regex": code.add(f"{field_name}: Variable::regex_zero_value(),") + elif field_var_type.type.name == "vec_iter": + code.add(f"{field_name}: Variable::None,") # TODO this is hacky else: + if field_var_type.type.name in self.builtin_type_names: + raise NotImplementedError # TODO + rust_struct_name = self._generate_type_name(field_var_type.type) code.add( f"{field_name}: Variable::UserType(Rc::new(RefCell::new(" diff --git a/zip.aaa b/zip.aaa new file mode 100644 index 00000000..6bb0ff33 --- /dev/null +++ b/zip.aaa @@ -0,0 +1,67 @@ +struct Tuple[A, B] { + a as A, + b as B, +} + +struct Zip[A, B] { + a as vec_iter[A], + b as vec_iter[B], +} + +fn zip[A, B] args a as vec[A], b as vec[B] return Zip[A, B] { + if a vec:len b vec:len != { + "zipping for vectors of inequal length is not allowed!\n" . + 1 exit + } + + Zip[A, B] + dup "a" { a vec:iter } ! + dup "b" { b vec:iter } ! +} + +fn Zip[A, B]:iter args z as Zip[A, B] return Zip[A, B] { + z +} + +fn Zip[A, B]:next args z as Zip[A, B] return Tuple[A, B], bool { + z "a" ? vec_iter:next + z "b" ? vec_iter:next + + use a, a_ok, b, b_ok { + Tuple[A, B] + + if a_ok { + dup "a" { a } ! + dup "b" { b } ! + } + a_ok + } +} + +fn main { + vec[int] + dup 1 vec:push + dup 2 vec:push + dup 3 vec:push + + vec[str] + dup "a" vec:push + dup "b" vec:push + dup "c" vec:push + + use numbers, chars { + numbers chars zip + foreach { + use tuple { + tuple "a" ? + tuple "b" ? + use number, char { + number . + " " . + char . + "\n" . + } + } + } + } +}