deprecate coroutine
[hiphop-php.git] / hphp / hack / src / parser / ocaml_syntax.rs
blob8f92aaa5f6ae229941b7c91b3e4b3db8175393ce
1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
3 //
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,
19 use rust_to_ocaml::*;
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,
27     pub value: V,
30 pub trait Context {
31     fn serialization_context(&self) -> &SerializationContext;
34 impl<V> OcamlSyntax<V>
35 where
36     V: SyntaxValueType<PositionedToken> + ToOcaml,
38     pub fn make<C: Context>(
39         ctx: &C,
40         kind: SyntaxKind,
41         value: &V,
42         children: &[OcamlValue],
43     ) -> OcamlValue {
44         unsafe {
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);
49             }
50             let node = reserve_block(0, 2);
51             caml_set_field(node, 0, syntax);
52             caml_set_field(node, 1, ocaml_value);
53             node
54         }
55     }
58 impl<V, C> SyntaxTypeBase<'_, C> for OcamlSyntax<V>
59 where
60     C: Context,
61     V: SyntaxValueType<PositionedToken> + ToOcaml,
63     type Token = PositionedToken;
64     type Value = V;
66     fn make_missing(ctx: &C, offset: usize) -> Self {
67         unsafe {
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);
74             Self {
75                 syntax: node,
76                 value,
77             }
78         }
79     }
81     fn make_token(ctx: &C, arg: Self::Token) -> Self {
82         unsafe {
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);
90             Self {
91                 syntax: node,
92                 value,
93             }
94         }
95     }
97     fn make_list(ctx: &C, args: Vec<Self>, offset: usize) -> Self {
98         unsafe {
99             if args.is_empty() {
100                 Self::make_missing(ctx, offset)
101             } else {
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);
111                 Self {
112                     syntax: node,
113                     value,
114                 }
115             }
116         }
117     }
119     fn value(&self) -> &Self::Value {
120         &self.value
121     }
124 impl<V> ToOcaml for OcamlSyntax<V> {
125     unsafe fn to_ocaml(&self, _context: &SerializationContext) -> Value {
126         self.syntax
127     }