Compare commits
13 Commits
antiquated
...
5fcb3b4f3b
Author | SHA1 | Date | |
---|---|---|---|
|
5fcb3b4f3b | ||
|
1f4ea71cf9 | ||
|
cd49c2c78f | ||
|
b1ffcd709b | ||
|
84455d11d5 | ||
|
16559d2e55 | ||
|
43cad55735 | ||
|
a6d065864c | ||
|
e2fc454c82 | ||
|
54649246b0 | ||
|
6759640389 | ||
|
c6b0f7d7d1 | ||
|
b7f7ba57d7 |
57
Cargo.lock
generated
57
Cargo.lock
generated
@ -87,6 +87,11 @@ name = "byteorder"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.45"
|
||||
@ -124,6 +129,15 @@ dependencies = [
|
||||
"winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.4"
|
||||
@ -282,6 +296,18 @@ name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.62"
|
||||
@ -382,6 +408,16 @@ dependencies = [
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.42"
|
||||
@ -729,6 +765,14 @@ name = "rustc-serialize"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.0"
|
||||
@ -748,12 +792,14 @@ name = "schala-lang"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"combine 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"derivative 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nom 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"radix_trie 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"schala-lang-codegen 0.1.0",
|
||||
"schala-repl 0.1.0",
|
||||
@ -846,6 +892,11 @@ name = "smallvec"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "stopwatch"
|
||||
version = "0.0.7"
|
||||
@ -1014,11 +1065,13 @@ dependencies = [
|
||||
"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2"
|
||||
"checksum blake2b_simd 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5850aeee1552f495dd0250014cf64b82b7c8879a89d83b33bbdace2cc4f63182"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
|
||||
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cdb90b60f2927f8d76139c72dbde7e10c3a2bc47c8594c9c7a66529f2687c03"
|
||||
"checksum combine 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c875843236b5e2eb535fd0b696387bfb623f896479b10ed626cf442b836e8032"
|
||||
"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120"
|
||||
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
|
||||
"checksum derivative 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "942ca430eef7a3806595a6737bc388bf51adb888d3fc0dd1b50f1c170167ee3a"
|
||||
@ -1040,6 +1093,7 @@ dependencies = [
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2304bccb228c4b020f3a4835d247df0a02a7c4686098d4167762cfbbe4c5cb14"
|
||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||
"checksum linefeed 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28715d08e35c6c074f9ae6b2e6a2420bac75d050c66ecd669d7d5b98e2caa036"
|
||||
"checksum llvm-sys 70.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e8e9fc46a848cf4170694144102ec07f6eada790d8b3d7e92ffa9cc7416fc869"
|
||||
@ -1052,6 +1106,7 @@ dependencies = [
|
||||
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||
"checksum nom 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c433f4d505fe6ce7ff78523d2fa13a0b9f2690e181fc26168bcbe5ccc5d14e07"
|
||||
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
|
||||
"checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1"
|
||||
"checksum num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656"
|
||||
@ -1091,6 +1146,7 @@ dependencies = [
|
||||
"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf"
|
||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
@ -1100,6 +1156,7 @@ dependencies = [
|
||||
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
|
||||
"checksum smallstr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa65bb4d5b2bbc90d36af64e29802f788aa614783fa1d0df011800ddcec6e8e"
|
||||
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
|
||||
"checksum static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
||||
"checksum stopwatch 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3d04b5ebc78da44d3a456319d8bc2783e7d8cc7ccbb5cb4dc3f54afbd93bf728"
|
||||
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
|
||||
|
3
TODO.md
3
TODO.md
@ -1,5 +1,8 @@
|
||||
# Plan of attack
|
||||
|
||||
-ONLY two types of statement, Expressoin and Declaration
|
||||
-modules and imports are just types of Declarables
|
||||
|
||||
1. modify visitor so it can handle scopes
|
||||
-this is needed both to handle import scope correctly
|
||||
-and also to support making FQSNs aware of function parameters
|
||||
|
@ -15,6 +15,8 @@ stopwatch = "0.0.7"
|
||||
derivative = "1.0.3"
|
||||
colored = "1.8"
|
||||
radix_trie = "0.1.5"
|
||||
nom = "5.1.0"
|
||||
combine = "4.0.1"
|
||||
|
||||
schala-lang-codegen = { path = "../codegen" }
|
||||
schala-repl = { path = "../../schala-repl" }
|
||||
|
@ -17,7 +17,7 @@ pub struct ItemId {
|
||||
}
|
||||
|
||||
impl ItemId {
|
||||
fn new(n: u32) -> ItemId {
|
||||
pub fn new(n: u32) -> ItemId {
|
||||
ItemId { idx: n }
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,10 @@ impl BinOp {
|
||||
let s = token_kind_to_sigil(op_tok)?;
|
||||
Some(binop_precedences(s))
|
||||
}
|
||||
|
||||
pub fn precedence(&self) -> i32 {
|
||||
binop_precedences(self.sigil.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
fn token_kind_to_sigil<'a>(tok: &'a TokenKind) -> Option<&'a str> {
|
||||
|
@ -32,6 +32,7 @@ mod debugging;
|
||||
|
||||
mod tokenizing;
|
||||
mod ast;
|
||||
mod parser;
|
||||
mod parsing;
|
||||
#[macro_use]
|
||||
mod symbol_table;
|
||||
|
255
schala-lang/language/src/parser.rs
Normal file
255
schala-lang/language/src/parser.rs
Normal file
@ -0,0 +1,255 @@
|
||||
extern crate nom;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
|
||||
use nom::IResult;
|
||||
use nom::character::complete::{one_of, space0, alphanumeric0};
|
||||
use nom::bytes::complete::{tag, take, take_while, take_until};
|
||||
use nom::combinator::{map, map_res, value, opt, verify};
|
||||
use nom::multi::{separated_list, separated_nonempty_list, many1, many0};
|
||||
use nom::error::{context, VerboseError};
|
||||
use nom::branch::alt;
|
||||
use nom::sequence::{pair, delimited};
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::builtin::Builtin;
|
||||
|
||||
type ParseResult<'a, T> = IResult<&'a str, T, VerboseError<&'a str>>;
|
||||
|
||||
|
||||
fn single_alphabetic_character(text: &str) -> ParseResult<char> {
|
||||
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphabetic()).unwrap_or(false));
|
||||
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
||||
}
|
||||
|
||||
fn single_alphanumeric_character(text: &str) -> ParseResult<char> {
|
||||
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphanumeric() || c == '_').unwrap_or(false));
|
||||
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
||||
}
|
||||
|
||||
fn identifier(text: &str) -> ParseResult<Rc<String>> {
|
||||
use nom::character::complete::char;
|
||||
context("Identifier", map(alt((
|
||||
pair(char('_'), many1(single_alphanumeric_character)),
|
||||
pair(single_alphabetic_character, many0(single_alphanumeric_character))
|
||||
)),
|
||||
|(first, rest): (char, Vec<char>)| Rc::new(format!("{}{}", first, rest.into_iter().collect::<String>()))
|
||||
))(text)
|
||||
}
|
||||
|
||||
const OPERATOR_CHARS: &'static str = "~`!@#$%^&*-+=<>?/|";
|
||||
fn parse_binop(text: &str) -> ParseResult<BinOp> {
|
||||
let p = many1(one_of(OPERATOR_CHARS));
|
||||
context("Binop", map(p,
|
||||
|op: Vec<char>| BinOp::from_sigil(&op.into_iter().collect::<String>())
|
||||
))(text)
|
||||
}
|
||||
|
||||
fn parse_bool_literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||
let p = alt((
|
||||
value(true, tag("true")),
|
||||
value(false, tag("false"))
|
||||
));
|
||||
context("Bool literal", map(p, ExpressionKind::BoolLiteral))(text)
|
||||
}
|
||||
|
||||
fn parse_number_literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||
let num_lit = many1(alt((
|
||||
map(one_of("1234567890"), |s: char| Some(s)),
|
||||
map(nom::character::complete::char('_'), |_| None)
|
||||
)));
|
||||
|
||||
let (text, n) = context("Number literal", map_res(num_lit,
|
||||
|digits: Vec<Option<char>>| {
|
||||
let num_str: String = digits.into_iter().filter_map(|x| x).collect();
|
||||
u64::from_str_radix(&num_str, 10)
|
||||
}))(text)?;
|
||||
|
||||
Ok((text, ExpressionKind::NatLiteral(n)))
|
||||
}
|
||||
|
||||
|
||||
fn parse_binary_literal(input: &str) -> ParseResult<ExpressionKind> {
|
||||
let (rest, _) = tag("0b")(input)?;
|
||||
let (rest, n): (&str, u64) = map_res(
|
||||
take_while(|c: char| c == '0' || c == '1'),
|
||||
|hex_str: &str| u64::from_str_radix(hex_str, 2)
|
||||
)(rest)?;
|
||||
let expr = ExpressionKind::NatLiteral(n);
|
||||
Ok((rest, expr))
|
||||
}
|
||||
|
||||
fn parse_hex_literal(input: &str) -> ParseResult<ExpressionKind> {
|
||||
let (rest, _) = tag("0x")(input)?;
|
||||
let (rest, n): (&str, u64) = map_res(
|
||||
take_while(|c: char| c.is_digit(16)),
|
||||
|hex_str: &str| u64::from_str_radix(hex_str, 16)
|
||||
)(rest)?;
|
||||
let expr = ExpressionKind::NatLiteral(n);
|
||||
Ok((rest, expr))
|
||||
}
|
||||
|
||||
fn parse_string_literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||
use nom::character::complete::char;
|
||||
let p = delimited(char('"'), take_until("\""), char('"'));
|
||||
context("String literal", map(p,
|
||||
|s: &str| ExpressionKind::StringLiteral(Rc::new(s.to_string()))
|
||||
))(text)
|
||||
}
|
||||
|
||||
fn literal(input: &str) -> ParseResult<ExpressionKind> {
|
||||
context("Literal", alt((
|
||||
parse_hex_literal,
|
||||
parse_binary_literal,
|
||||
parse_number_literal,
|
||||
parse_bool_literal,
|
||||
parse_string_literal,
|
||||
)))(input)
|
||||
}
|
||||
|
||||
fn paren_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
use nom::character::complete::char;
|
||||
context("Paren expression", delimited(char('('), expression_kind, char(')')))(text)
|
||||
}
|
||||
|
||||
fn prefix_op(input: &str) -> ParseResult<PrefixOp> {
|
||||
use nom::character::complete::char;
|
||||
let p = alt((char('+'), char('-'), char('!')));
|
||||
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(input)
|
||||
}
|
||||
|
||||
fn identifier_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
let (text, qualified_identifier) = map(
|
||||
qualified_identifier_list,
|
||||
|components| QualifiedName { id: ItemId::new(0), components }
|
||||
)(text)?;
|
||||
//TODO handle struct literals
|
||||
let exp = Expression::new(ItemId::new(0), ExpressionKind::Value(qualified_identifier));
|
||||
Ok((text, exp.kind))
|
||||
}
|
||||
|
||||
fn qualified_identifier_list(text: &str) -> ParseResult<Vec<Rc<String>>> {
|
||||
context("Qualified identifier list", separated_nonempty_list(tag("::"), identifier))(text)
|
||||
}
|
||||
|
||||
fn primary_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
// primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_expr | lambda_expr | anonymous_struct | list_expr
|
||||
|
||||
alt((
|
||||
literal,
|
||||
paren_expr,
|
||||
identifier_expr,
|
||||
))(text)
|
||||
}
|
||||
|
||||
fn invocation_argument(text: &str) -> ParseResult<InvocationArgument> {
|
||||
use nom::character::complete::char;
|
||||
alt((
|
||||
value(InvocationArgument::Ignored, pair(char('_'), alphanumeric0)),
|
||||
map(expression_kind, |kind: ExpressionKind| InvocationArgument::Positional(
|
||||
Expression { id: ItemId::new(0), kind, type_anno: None }))
|
||||
//map(identifier, |id: Rc<String>|
|
||||
))(text)
|
||||
}
|
||||
|
||||
fn call_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
use nom::character::complete::char;
|
||||
let (text, expr) = primary_expr(text)?;
|
||||
let (text, call_part) = opt(
|
||||
delimited(char('('), separated_list(char(','), invocation_argument), char(')'))
|
||||
)(text)?;
|
||||
let output = if let Some(arguments) = call_part {
|
||||
let f = bx!(Expression { id: ItemId::new(0), kind: expr, type_anno: None });
|
||||
ExpressionKind::Call { f, arguments }
|
||||
} else {
|
||||
expr
|
||||
};
|
||||
Ok((text, output))
|
||||
}
|
||||
|
||||
fn prefix_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?;
|
||||
let (text, result) = call_expr(text)?;
|
||||
match pfx {
|
||||
None => Ok((text, result)),
|
||||
Some(pfx) => {
|
||||
let exp = Expression { id: ItemId::new(0), kind: result, type_anno: None };
|
||||
Ok((text, ExpressionKind::PrefixExp(pfx, Box::new(exp))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
||||
fn precedence_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
fn inner_precedence_expr(input: &str, precedence: i32) -> ParseResult<ExpressionKind> {
|
||||
let (mut outer_rest, mut lhs) = prefix_expr(input)?;
|
||||
loop {
|
||||
let (rest, _) = space0(outer_rest)?;
|
||||
let (rest, maybe_binop) = opt(parse_binop)(rest)?;
|
||||
let (new_precedence, binop) = match maybe_binop {
|
||||
Some(binop) => (binop.precedence(), binop),
|
||||
None => break,
|
||||
};
|
||||
|
||||
if precedence >= new_precedence {
|
||||
break;
|
||||
}
|
||||
let (rest, _) = space0(rest)?;
|
||||
let (rest, rhs) = inner_precedence_expr(rest, new_precedence)?;
|
||||
outer_rest = rest;
|
||||
lhs = ExpressionKind::BinExp(binop,
|
||||
bx!(Expression::new(ItemId::new(0), lhs)),
|
||||
bx!(Expression::new(ItemId::new(0), rhs))
|
||||
);
|
||||
}
|
||||
Ok((outer_rest, lhs))
|
||||
}
|
||||
context("Precedence expression",
|
||||
|input| inner_precedence_expr(input, BinOp::min_precedence())
|
||||
)(text)
|
||||
}
|
||||
|
||||
fn expression_kind(text: &str) -> ParseResult<ExpressionKind> {
|
||||
precedence_expr(text)
|
||||
}
|
||||
|
||||
mod thing {
|
||||
use crate::ast::*;
|
||||
use crate::builtin::Builtin;
|
||||
|
||||
use combine::parser::range::{range, take_while1};
|
||||
use combine::parser::repeat::{many1, sep_by};
|
||||
use combine::Stream;
|
||||
use combine::*;
|
||||
|
||||
fn number_literal<I>(input: &str) -> impl Parser<I, Output=u64>
|
||||
where I: Stream<Token = char>, I::Error: ParseError<I::Token, I::Range, I::Position> {
|
||||
|
||||
use combine::parser::char::digit;
|
||||
|
||||
many1(digit())
|
||||
.flat_map(|digits: Vec<char>| {
|
||||
//let num_str: String = digits.into_iter().filter_map(|x| x).collect();
|
||||
let num_str: String = digits.into_iter().collect();
|
||||
u64::from_str_radix(&num_str, 10)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
pub fn perform_parsing(input: &str) -> String {
|
||||
use combine::parser::char::char;
|
||||
//let identifier = take_while1(|c: char| c.is_alphabetic());
|
||||
//let mut parser = sep_by(identifier, range(", "));
|
||||
let parser = sep_by(char(','), number_literal);
|
||||
let result: Result<(Vec<&str>, &str), _> = parser.easy_parse(input);
|
||||
format!("{:?}", result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn perform_parsing(input: &str) -> Result<String, String> {
|
||||
// let output = expression_kind(input)
|
||||
let output = thing::perform_parsing(input);
|
||||
Ok(output)
|
||||
}
|
@ -10,7 +10,7 @@ use schala_repl::{ProgrammingLanguageInterface,
|
||||
ComputationRequest, ComputationResponse,
|
||||
LangMetaRequest, LangMetaResponse, GlobalOutputStats,
|
||||
DebugResponse, DebugAsk};
|
||||
use crate::{ast, reduced_ast, tokenizing, parsing, eval, typechecking, symbol_table, source_map};
|
||||
use crate::{ast, reduced_ast, tokenizing, parsing, parser, eval, typechecking, symbol_table, source_map};
|
||||
|
||||
pub type SymbolTableHandle = Rc<RefCell<symbol_table::SymbolTable>>;
|
||||
pub type SourceMapHandle = Rc<RefCell<source_map::SourceMap>>;
|
||||
@ -319,6 +319,8 @@ impl ProgrammingLanguageInterface for Schala {
|
||||
total_duration, stage_durations
|
||||
};
|
||||
|
||||
let main_output = parser::perform_parsing(source);
|
||||
|
||||
ComputationResponse {
|
||||
main_output,
|
||||
global_output_stats,
|
||||
|
Loading…
Reference in New Issue
Block a user