1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
4 // This source code is licensed under the MIT license found in the
5 // LICENSE file in the "hack" directory of this source tree.
7 pub mod ocaml_context_state;
8 mod ocaml_syntax_generated;
10 use ocaml::core::mlvalues::Value as OcamlValue;
11 use ocaml::core::mlvalues::Value;
12 use ocamlpool_rust::utils::*;
13 use parser_core_types::{
14 lexable_token::LexableToken,
15 positioned_token::PositionedToken,
16 syntax::{SyntaxTypeBase, SyntaxValueType},
17 syntax_kind::SyntaxKind,
21 pub use crate::ocaml_context_state::*;
22 pub use crate::ocaml_syntax_generated::*;
24 #[derive(Debug, Clone)]
25 pub struct OcamlSyntax<V> {
26 pub syntax: OcamlValue,
31 fn serialization_context(&self) -> &SerializationContext;
34 impl<V> OcamlSyntax<V>
36 V: SyntaxValueType<PositionedToken> + ToOcaml,
38 pub fn make<C: Context>(
42 children: &[OcamlValue],
45 let ocaml_value = value.to_ocaml(ctx.serialization_context());
46 let syntax = reserve_block(kind.ocaml_tag().into(), children.len());
47 for (i, &child) in children.iter().enumerate() {
48 caml_set_field(syntax, i, child);
50 let node = reserve_block(0, 2);
51 caml_set_field(node, 0, syntax);
52 caml_set_field(node, 1, ocaml_value);
58 impl<V, C> SyntaxTypeBase<'_, C> for OcamlSyntax<V>
61 V: SyntaxValueType<PositionedToken> + ToOcaml,
63 type Token = PositionedToken;
66 fn make_missing(ctx: &C, offset: usize) -> Self {
68 let value = V::from_children(SyntaxKind::Missing, offset, &[]);
69 let ocaml_value = value.to_ocaml(ctx.serialization_context());
70 let kind = u8_to_ocaml(SyntaxKind::Missing.ocaml_tag());
71 let node = reserve_block(0, 2);
72 caml_set_field(node, 0, kind);
73 caml_set_field(node, 1, ocaml_value);
81 fn make_token(ctx: &C, arg: Self::Token) -> Self {
83 let value = V::from_token(&arg);
84 let ocaml_value = value.to_ocaml(ctx.serialization_context());
85 let syntax = reserve_block(SyntaxKind::Token(arg.kind()).ocaml_tag().into(), 1);
86 caml_set_field(syntax, 0, arg.to_ocaml(ctx.serialization_context()));
87 let node = reserve_block(0.into(), 2);
88 caml_set_field(node, 0, syntax);
89 caml_set_field(node, 1, ocaml_value);
97 fn make_list(ctx: &C, args: Vec<Self>, offset: usize) -> Self {
100 Self::make_missing(ctx, offset)
102 // TODO: avoid creating Vec
103 let lst_slice = &args.iter().map(|x| &x.value).collect::<Vec<_>>();
104 let value = V::from_children(SyntaxKind::SyntaxList, offset, lst_slice);
105 let ocaml_value = value.to_ocaml(ctx.serialization_context());
106 let syntax = reserve_block(SyntaxKind::SyntaxList.ocaml_tag().into(), 1);
107 caml_set_field(syntax, 0, to_list(&args, ctx.serialization_context()));
108 let node = reserve_block(0.into(), 2);
109 caml_set_field(node, 0, syntax);
110 caml_set_field(node, 1, ocaml_value);
119 fn value(&self) -> &Self::Value {
124 impl<V> ToOcaml for OcamlSyntax<V> {
125 unsafe fn to_ocaml(&self, _context: &SerializationContext) -> Value {