Skip to content

Instantly share code, notes, and snippets.

@amieres
amieres / SeqExtensions.fs
Last active December 9, 2023 17:27
Seq.splitBy, Seq.splitAt, Seq.tryHeadTail
module Seq
type [< RequireQualifiedAccess >] SplitByOption = Exclude | IncludeInFirst | IncludeInSecond
type [< RequireQualifiedAccess >] private SplitSubUnfoldState<'T> =
| PostValue of 'T * SplitSubUnfoldState<'T>
| Start of seqNo: int * start: int
| Started of tryNext: (unit -> 'T option) * bingo: ('T -> unit) * finish: (unit -> unit)
| Finish
type [< RequireQualifiedAccess >] private SplitUnfoldState<'T> = {
module Regex =
open System.Text.RegularExpressions
type REx = REx of string with
member r.txt = let (REx t) = r in t
static member (+)(REx a, REx b) = REx(a + b)
let rex (REx v) = v
let (|Regex|_|) (REx pattern) input =
@amieres
amieres / Msal.fs
Created April 2, 2019 19:09
Preamble for Msal.js & Azure AD B2C
#I @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1"
#I @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades"
#I @"D:\Abe\CIPHERWorkspace\FSharpStation\packages\WebSharper\lib\net461"
#I @"D:\Abe\CIPHERWorkspace\FSharpStation\packages\WebSharper.UI\lib\net461"
#r @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll"
#r @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Core.dll"
#r @"D:\Abe\CIPHERWorkspace\FSharpStation\packages\WebSharper\lib\net461\WebSharper.Core.dll"
#r @"D:\Abe\CIPHERWorkspace\FSharpStation\packages\WebSharper\lib\net461\WebSharper.Core.JavaScript.dll"
#r @"D:\Abe\CIPHERWorkspace\FSharpStation\packages\WebSharper\lib\net461\WebSharper.Collections.dll"
#r @"D:\Abe\CIPHERWorkspace\FSharpStation\packages\WebSharper\lib\net461\WebSharper.InterfaceGenerator.dll"
private void button1_Click(object sender,EventArgs e) {
Parser P = new Parser(this.textBox1.Text);
if (P.Parse())
this.textBox2.Text = "Success!";
else
this.textBox2.Text = "Failed at " + P.Position.ToString();
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace SimpleParser {
class Parser {
public Parser(string Text) {
Input = Text;
String Input = null;
int LastPosition = -1;
int SpaceLength = 0;
void SkipSpacesComments() {
if (Position == LastPosition) return;
LastPosition = Position;
CurrentString = Input.Substring(Position);
string RegEx = "^([ \\t\\n\\r]|\\/\\*.*?\\*\\/)*";
Match M = Regex.Match(CurrentString, RegEx);
public int Position = 0;
String Token = null;
string CurrentString;
bool R(string RegEx) {
SkipSpacesComments();
Match M = Regex.Match(CurrentString, "^" + RegEx
, RegexOptions.IgnoreCase);
if (M.Success) {
Token = CurrentString.Substring(0, M.Length);
public bool Stopping = false;
bool P(rule R) {
if (Stopping) return false;
int StartingPosition = Position;
bool Result = R();
if (!Result && StartingPosition != Position)
Stopping = true;
return Result;
}
wexpr = () => P(() => expr(0) && EOS() );
expr = (L) => P(() => mexpr() && expr2(L) );
expr2 = (L) => P(() => L < 4 && C("+") && expr(4) && expr2(L) )
|| P(() => L < 4 && C("-") && expr(4) && expr2(L) )
|| P(() => L < 5 && C("*") && expr(5) && expr2(L) )
|| P(() => L < 5 && C("/") && expr(5) && expr2(L) )
|| P(() => L < 2 && C("<=") && expr(2) && expr2(L) )
|| P(() => L < 2 && C(">=") && expr(2) && expr2(L) )
wexpr => expr(0) EOS
expr(L) => mexpr expr2(L)
expr2(L)=> L < 4 "+" expr(4) expr2(L)
=> L < 4 "-" expr(4) expr2(L)
=> L < 5 "*" expr(5) expr2(L)
=> L < 5 "/" expr(5) expr2(L)
=> L < 2 "<=" expr(2) expr2(L)
=> L < 2 ">=" expr(2) expr2(L)