Skip to content
This repository was archived by the owner on Jul 6, 2019. It is now read-only.

Commit 7bcf91c

Browse files
committed
Merge pull request #108 from bgamari/ioreg-rebased
ioreg syntax extension Reviewed-by: farcaller
2 parents 7ee618e + bf1fe45 commit 7bcf91c

File tree

13 files changed

+2390
-3
lines changed

13 files changed

+2390
-3
lines changed

Rakefile

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,26 @@ compile_rust :core_crate, {
3434
recompile_on: :triple,
3535
}
3636

37+
# ioreg
38+
compile_rust :ioreg_crate, {
39+
source: 'ioreg/ioreg.rs'.in_root,
40+
produce: 'ioreg/ioreg.rs'.in_root.as_rlib.in_build,
41+
out_dir: true,
42+
build_for: :host,
43+
}
44+
45+
compile_rust :macro_ioreg, {
46+
source: 'macro/ioreg.rs'.in_root,
47+
deps: [:ioreg_crate],
48+
produce: 'macro/ioreg.rs'.in_root.as_dylib.in_build,
49+
out_dir: true,
50+
build_for: :host,
51+
}
52+
3753
# zinc crate
3854
compile_rust :zinc_crate, {
3955
source: 'main.rs'.in_source,
40-
deps: [:core_crate, :rlibc_crate],
56+
deps: [:core_crate, :rlibc_crate, :macro_ioreg],
4157
produce: 'main.rs'.in_source.as_rlib.in_build,
4258
out_dir: true,
4359
recompile_on: [:triple, :platform],
@@ -96,8 +112,10 @@ desc "Build API documentation"
96112
task build_docs: [:build_docs_html]
97113

98114
task build_docs_html: [] do |t|
99-
['src/main.rs', 'platformtree/platformtree.rs'].each do |f|
100-
sh ("rustdoc -w html -o build/doc " + f + ' ' + :config_flags.in_env.join(' '))
115+
['src/main.rs', 'platformtree/platformtree.rs', 'ioreg/ioreg.rs'].each do |f|
116+
build = Context.instance.build_dir
117+
sh ("rustdoc -w html -o #{build}/doc -L #{build} " \
118+
+ f + ' ' + :config_flags.in_env.join(' '))
101119
end
102120
end
103121

ioreg/builder/accessors.rs

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Zinc, the bare metal stack for rust.
2+
// Copyright 2014 Ben Gamari <[email protected]>
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
use syntax::ast;
17+
use syntax::ast::P;
18+
use syntax::codemap::DUMMY_SP;
19+
use syntax::ext::base::ExtCtxt;
20+
use syntax::ext::build::AstBuilder;
21+
use syntax::ext::quote::rt::ToTokens;
22+
use syntax::parse::token;
23+
24+
use super::Builder;
25+
use super::utils;
26+
use super::super::node;
27+
28+
/// A visitor to build accessor functions for each register struct
29+
pub struct BuildAccessors<'a, 'b, 'c> {
30+
builder: &'a mut Builder,
31+
cx: &'b ExtCtxt<'c>,
32+
}
33+
34+
impl<'a, 'b, 'c> node::RegVisitor for BuildAccessors<'a, 'b, 'c> {
35+
fn visit_prim_reg(&mut self, path: &Vec<String>, reg: &node::Reg,
36+
_width: node::RegWidth, fields: &Vec<node::Field>) {
37+
let item = build_get_fn(self.cx, path, reg);
38+
self.builder.push_item(item);
39+
40+
for field in fields.iter() {
41+
match build_field_accessors(self.cx, path, reg, field) {
42+
Some(item) => self.builder.push_item(item),
43+
None => {}
44+
}
45+
}
46+
}
47+
}
48+
49+
impl<'a, 'b, 'c> BuildAccessors<'a, 'b, 'c> {
50+
pub fn new(builder: &'a mut Builder, cx: &'b ExtCtxt<'c>)
51+
-> BuildAccessors<'a, 'b, 'c> {
52+
BuildAccessors {builder: builder, cx: cx}
53+
}
54+
}
55+
56+
fn build_field_accessors<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
57+
reg: &node::Reg, field: &node::Field)
58+
-> Option<P<ast::Item>>
59+
{
60+
let reg_ty: P<ast::Ty> =
61+
cx.ty_ident(DUMMY_SP, utils::path_ident(cx, path));
62+
63+
let items = match field.access {
64+
node::ReadWrite => vec!(build_field_set_fn(cx, path, reg, field),
65+
build_field_get_fn(cx, path, reg, field)),
66+
node::ReadOnly => vec!(build_field_get_fn(cx, path, reg, field)),
67+
node::WriteOnly => vec!(build_field_set_fn(cx, path, reg, field)),
68+
node::SetToClear => vec!(build_field_clear_fn(cx, path, reg, field)),
69+
};
70+
71+
let access_tag = match field.access {
72+
node::ReadWrite => "read/write",
73+
node::ReadOnly => "read-only",
74+
node::WriteOnly => "write-only",
75+
node::SetToClear => "set-to-clear",
76+
};
77+
78+
let field_doc = match field.docstring {
79+
Some(ref d) => {
80+
let s = token::get_ident(d.node);
81+
s.get().into_string()
82+
},
83+
None => "no documentation".into_string()
84+
};
85+
let docstring = format!("*[{}]* Field `{}`: {}",
86+
access_tag,
87+
field.name.node,
88+
field_doc);
89+
let doc_attr = utils::doc_attribute(cx, utils::intern_string(cx, docstring));
90+
91+
quote_item!(cx,
92+
$doc_attr
93+
impl $reg_ty {
94+
$items
95+
}
96+
)
97+
}
98+
99+
fn build_get_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>, reg: &node::Reg)
100+
-> P<ast::Item>
101+
{
102+
let reg_ty: P<ast::Ty> =
103+
cx.ty_ident(DUMMY_SP, utils::path_ident(cx, path));
104+
let getter_ty = utils::getter_name(cx, path);
105+
106+
let docstring = format!("Fetch the value of the `{}` register",
107+
reg.name.node);
108+
let doc_attr = utils::doc_attribute(cx, utils::intern_string(cx, docstring));
109+
110+
let item = quote_item!(cx,
111+
impl $reg_ty {
112+
$doc_attr
113+
#[allow(dead_code)]
114+
pub fn get(&'static self) -> $getter_ty {
115+
$getter_ty::new(self)
116+
}
117+
}
118+
);
119+
item.unwrap()
120+
}
121+
122+
fn build_field_set_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
123+
reg: &node::Reg, field: &node::Field)
124+
-> P<ast::Method>
125+
{
126+
let fn_name =
127+
cx.ident_of((String::from_str("set_")+field.name.node).as_slice());
128+
let field_ty: P<ast::Ty> =
129+
cx.ty_path(utils::field_type_path(cx, path, reg, field), None);
130+
let setter_ty = utils::setter_name(cx, path);
131+
if field.count.node == 1 {
132+
quote_method!(cx,
133+
#[allow(dead_code, missing_doc)]
134+
pub fn $fn_name(&'static self, new_value: $field_ty) -> $setter_ty {
135+
let mut setter: $setter_ty = $setter_ty::new(self);
136+
setter.$fn_name(new_value);
137+
setter
138+
}
139+
)
140+
} else {
141+
quote_method!(cx,
142+
#[allow(dead_code, missing_doc)]
143+
pub fn $fn_name(&'static self, idx: uint, new_value: $field_ty) -> $setter_ty {
144+
let mut setter: $setter_ty = $setter_ty::new(self);
145+
setter.$fn_name(idx, new_value);
146+
setter
147+
}
148+
)
149+
}
150+
}
151+
152+
fn build_field_get_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
153+
reg: &node::Reg, field: &node::Field)
154+
-> P<ast::Method>
155+
{
156+
let fn_name = cx.ident_of(field.name.node.as_slice());
157+
let field_ty: P<ast::Ty> =
158+
cx.ty_path(utils::field_type_path(cx, path, reg, field), None);
159+
let getter_ty = utils::getter_name(cx, path);
160+
if field.count.node == 1 {
161+
quote_method!(cx,
162+
#[allow(dead_code, missing_doc)]
163+
pub fn $fn_name(&'static self) -> $field_ty {
164+
$getter_ty::new(self).$fn_name()
165+
}
166+
)
167+
} else {
168+
quote_method!(cx,
169+
#[allow(dead_code, missing_doc)]
170+
pub fn $fn_name(&'static self, idx: uint) -> $field_ty {
171+
$getter_ty::new(self).$fn_name(idx)
172+
}
173+
)
174+
}
175+
}
176+
177+
fn build_field_clear_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
178+
_reg: &node::Reg, field: &node::Field)
179+
-> P<ast::Method>
180+
{
181+
let fn_name =
182+
cx.ident_of((String::from_str("clear_")+field.name.node).as_slice());
183+
let setter_ty = utils::setter_name(cx, path);
184+
if field.count.node == 1 {
185+
quote_method!(cx,
186+
#[allow(dead_code, missing_doc)]
187+
pub fn $fn_name(&'static self) -> $setter_ty {
188+
let mut setter: $setter_ty = $setter_ty::new(self);
189+
setter.$fn_name();
190+
setter
191+
}
192+
)
193+
} else {
194+
quote_method!(cx,
195+
#[allow(dead_code, missing_doc)]
196+
pub fn $fn_name(&'static self, idx: uint) -> $setter_ty {
197+
let mut setter: $setter_ty = $setter_ty::new(self);
198+
setter.$fn_name(idx);
199+
setter
200+
}
201+
)
202+
}
203+
}

0 commit comments

Comments
 (0)