mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 04:44:44 +00:00
Implement Record/TupleTypeSpec
This commit is contained in:
parent
9a88266bde
commit
b28c6bd118
5 changed files with 83 additions and 4 deletions
|
@ -6,7 +6,7 @@ use std::process::Command;
|
||||||
use crate::serialize::get_magic_num_from_bytes;
|
use crate::serialize::get_magic_num_from_bytes;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub const BUILTIN_PYTHON_MODS: [&str; 20] = [
|
pub const BUILTIN_PYTHON_MODS: [&str; 21] = [
|
||||||
"datetime",
|
"datetime",
|
||||||
"glob",
|
"glob",
|
||||||
"http",
|
"http",
|
||||||
|
@ -15,6 +15,7 @@ pub const BUILTIN_PYTHON_MODS: [&str; 20] = [
|
||||||
"json",
|
"json",
|
||||||
"math",
|
"math",
|
||||||
"os",
|
"os",
|
||||||
|
"platform",
|
||||||
"posix",
|
"posix",
|
||||||
"random",
|
"random",
|
||||||
"re",
|
"re",
|
||||||
|
@ -29,7 +30,7 @@ pub const BUILTIN_PYTHON_MODS: [&str; 20] = [
|
||||||
"zipfile",
|
"zipfile",
|
||||||
];
|
];
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
pub const BUILTIN_PYTHON_MODS: [&str; 19] = [
|
pub const BUILTIN_PYTHON_MODS: [&str; 20] = [
|
||||||
"datetime",
|
"datetime",
|
||||||
"glob",
|
"glob",
|
||||||
"http",
|
"http",
|
||||||
|
@ -38,6 +39,7 @@ pub const BUILTIN_PYTHON_MODS: [&str; 19] = [
|
||||||
"json",
|
"json",
|
||||||
"math",
|
"math",
|
||||||
"os",
|
"os",
|
||||||
|
"platform",
|
||||||
"random",
|
"random",
|
||||||
"re",
|
"re",
|
||||||
"shutil",
|
"shutil",
|
||||||
|
|
|
@ -956,6 +956,22 @@ impl Context {
|
||||||
}
|
}
|
||||||
Ok(dict_t(inst_tys.into()))
|
Ok(dict_t(inst_tys.into()))
|
||||||
}
|
}
|
||||||
|
TypeSpec::Record(rec) => {
|
||||||
|
let mut inst_tys = dict! {};
|
||||||
|
for (k, v) in rec {
|
||||||
|
inst_tys.insert(
|
||||||
|
k.into(),
|
||||||
|
self.instantiate_typespec(
|
||||||
|
v,
|
||||||
|
opt_decl_t,
|
||||||
|
tmp_tv_ctx,
|
||||||
|
mode,
|
||||||
|
not_found_is_qvar,
|
||||||
|
)?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(Type::Record(inst_tys))
|
||||||
|
}
|
||||||
// TODO: エラー処理(リテラルでない)はパーサーにやらせる
|
// TODO: エラー処理(リテラルでない)はパーサーにやらせる
|
||||||
TypeSpec::Enum(set) => {
|
TypeSpec::Enum(set) => {
|
||||||
let mut new_set = set! {};
|
let mut new_set = set! {};
|
||||||
|
|
13
compiler/erg_compiler/lib/pystd/platform.d.er
Normal file
13
compiler/erg_compiler/lib/pystd/platform.d.er
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
.architecture!: () => Str
|
||||||
|
.machine!: () => Str
|
||||||
|
.node!: () => Str
|
||||||
|
.platform!: () => Str
|
||||||
|
.processor!: () => Str
|
||||||
|
.python_build!: () => Str
|
||||||
|
.python_compiler!: () => Str
|
||||||
|
.python_branch!: () => Str
|
||||||
|
.python_implementation!: () => Str
|
||||||
|
.python_revision!: () => Str
|
||||||
|
.python_version!: () => Str
|
||||||
|
.python_version_tuple!: () => (Str, Str, Str)
|
||||||
|
.uname!: () => {.system = Str; .node = Str; .release = Str; .version = Str; .machine = Str}
|
|
@ -1768,7 +1768,7 @@ pub enum TypeSpec {
|
||||||
Set(SetTypeSpec),
|
Set(SetTypeSpec),
|
||||||
Tuple(Vec<TypeSpec>),
|
Tuple(Vec<TypeSpec>),
|
||||||
Dict(Vec<(TypeSpec, TypeSpec)>),
|
Dict(Vec<(TypeSpec, TypeSpec)>),
|
||||||
// Dict(),
|
Record(Vec<(Identifier, TypeSpec)>),
|
||||||
// Option(),
|
// Option(),
|
||||||
And(Box<TypeSpec>, Box<TypeSpec>),
|
And(Box<TypeSpec>, Box<TypeSpec>),
|
||||||
Not(Box<TypeSpec>, Box<TypeSpec>),
|
Not(Box<TypeSpec>, Box<TypeSpec>),
|
||||||
|
@ -1799,11 +1799,18 @@ impl fmt::Display for TypeSpec {
|
||||||
Self::Tuple(tys) => write!(f, "({})", fmt_vec(tys)),
|
Self::Tuple(tys) => write!(f, "({})", fmt_vec(tys)),
|
||||||
Self::Dict(dict) => {
|
Self::Dict(dict) => {
|
||||||
write!(f, "{{")?;
|
write!(f, "{{")?;
|
||||||
for (k, v) in dict {
|
for (k, v) in dict.iter() {
|
||||||
write!(f, "{k}: {v}, ")?;
|
write!(f, "{k}: {v}, ")?;
|
||||||
}
|
}
|
||||||
write!(f, "}}")
|
write!(f, "}}")
|
||||||
}
|
}
|
||||||
|
Self::Record(rec) => {
|
||||||
|
write!(f, "{{")?;
|
||||||
|
for (k, v) in rec.iter() {
|
||||||
|
write!(f, "{k} = {v}; ")?;
|
||||||
|
}
|
||||||
|
write!(f, "}}")
|
||||||
|
}
|
||||||
Self::Enum(elems) => write!(f, "{{{elems}}}"),
|
Self::Enum(elems) => write!(f, "{{{elems}}}"),
|
||||||
Self::Interval { op, lhs, rhs } => write!(f, "{lhs}{}{rhs}", op.inspect()),
|
Self::Interval { op, lhs, rhs } => write!(f, "{lhs}{}{rhs}", op.inspect()),
|
||||||
Self::Subr(s) => write!(f, "{s}"),
|
Self::Subr(s) => write!(f, "{s}"),
|
||||||
|
@ -1824,6 +1831,7 @@ impl Locational for TypeSpec {
|
||||||
// TODO: ユニット
|
// TODO: ユニット
|
||||||
Self::Tuple(tys) => Location::concat(tys.first().unwrap(), tys.last().unwrap()),
|
Self::Tuple(tys) => Location::concat(tys.first().unwrap(), tys.last().unwrap()),
|
||||||
Self::Dict(dict) => Location::concat(&dict.first().unwrap().0, &dict.last().unwrap().1),
|
Self::Dict(dict) => Location::concat(&dict.first().unwrap().0, &dict.last().unwrap().1),
|
||||||
|
Self::Record(rec) => Location::concat(&rec.first().unwrap().0, &rec.last().unwrap().1),
|
||||||
Self::Enum(set) => set.loc(),
|
Self::Enum(set) => set.loc(),
|
||||||
Self::Interval { lhs, rhs, .. } => Location::concat(lhs, rhs),
|
Self::Interval { lhs, rhs, .. } => Location::concat(lhs, rhs),
|
||||||
Self::Subr(s) => s.loc(),
|
Self::Subr(s) => s.loc(),
|
||||||
|
|
|
@ -3046,6 +3046,38 @@ impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn record_to_record_type_spec(
|
||||||
|
record: Record,
|
||||||
|
) -> Result<Vec<(Identifier, TypeSpec)>, ParseError> {
|
||||||
|
match record {
|
||||||
|
Record::Normal(rec) => {
|
||||||
|
let mut rec_spec = vec![];
|
||||||
|
for mut def in rec.attrs.into_iter() {
|
||||||
|
let ident = def.sig.ident().unwrap().clone();
|
||||||
|
// TODO: check block.len() == 1
|
||||||
|
let value = Self::expr_to_type_spec(def.body.block.pop().unwrap())?;
|
||||||
|
rec_spec.push((ident, value));
|
||||||
|
}
|
||||||
|
Ok(rec_spec)
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tuple_to_tuple_type_spec(tuple: Tuple) -> Result<Vec<TypeSpec>, ParseError> {
|
||||||
|
match tuple {
|
||||||
|
Tuple::Normal(tup) => {
|
||||||
|
let mut tup_spec = vec![];
|
||||||
|
let (elems, ..) = tup.elems.deconstruct();
|
||||||
|
for elem in elems.into_iter() {
|
||||||
|
let value = Self::expr_to_type_spec(elem.expr)?;
|
||||||
|
tup_spec.push(value);
|
||||||
|
}
|
||||||
|
Ok(tup_spec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expr_to_type_spec(rhs: Expr) -> Result<TypeSpec, ParseError> {
|
pub fn expr_to_type_spec(rhs: Expr) -> Result<TypeSpec, ParseError> {
|
||||||
match rhs {
|
match rhs {
|
||||||
Expr::Accessor(acc) => Self::accessor_to_type_spec(acc),
|
Expr::Accessor(acc) => Self::accessor_to_type_spec(acc),
|
||||||
|
@ -3069,6 +3101,14 @@ impl Parser {
|
||||||
let dict = Self::dict_to_dict_type_spec(dict)?;
|
let dict = Self::dict_to_dict_type_spec(dict)?;
|
||||||
Ok(TypeSpec::Dict(dict))
|
Ok(TypeSpec::Dict(dict))
|
||||||
}
|
}
|
||||||
|
Expr::Record(rec) => {
|
||||||
|
let rec = Self::record_to_record_type_spec(rec)?;
|
||||||
|
Ok(TypeSpec::Record(rec))
|
||||||
|
}
|
||||||
|
Expr::Tuple(tup) => {
|
||||||
|
let tup = Self::tuple_to_tuple_type_spec(tup)?;
|
||||||
|
Ok(TypeSpec::Tuple(tup))
|
||||||
|
}
|
||||||
Expr::BinOp(bin) => {
|
Expr::BinOp(bin) => {
|
||||||
if bin.op.kind.is_range_op() {
|
if bin.op.kind.is_range_op() {
|
||||||
let op = bin.op;
|
let op = bin.op;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue