CVUParser.ts 27.72 KiB
//
//  Parser.swift
//
//  Based on work by Matthew Cheok on 15/11/15.
//  Copyright © 2015 Matthew Cheok. All rights reserved.
//  Copyright © 2020 memri. All rights reserved.
//
import {Expression} from "../expression-parser/Expression";
import {CVUToken, CVUOperator} from "./CVULexer";
import {CVUParseErrors} from "./CVUParseErrors";
import {
    CVUParsedStyleDefinition,
    CVUParsedColorDefinition,
    CVUParsedRendererDefinition,
    CVUParsedLanguageDefinition,
    CVUParsedViewDefinition,
    CVUParsedSessionsDefinition,
    CVUParsedDatasourceDefinition,
    CVUParsedSessionDefinition, CVUParsedObjectDefinition
} from "./CVUParsedDefinition"
import {ActionFamily, getActionType} from "../../cvu/views/Action";
import {UIElement, UIElementFamily} from "../../cvu/views/UIElement";
import {MemriDictionary} from "../../model/MemriDictionary";
export class Color {
    value;
    constructor(value) {
        switch (value) {
            case "systemBackground":
            case "white":
                this.value = "#ffffff";
                break;
            case "black":
                this.value = "#000000";
                break;
            default:
                if (value.charAt(0) == "#") {
                    if (value.length == 4) {
                        this.value = value.charAt(0) + value.charAt(1) + value.charAt(1) + value.charAt(2) + value.charAt(2) + value.charAt(3) + value.charAt(3);
                    } else {
                        this.value = value;
                } else {
                    if (value.length == 3) {
                        this.value = "#" + value.charAt(0) + value.charAt(0) + value.charAt(1) + value.charAt(1) + value.charAt(2) + value.charAt(2);
                    } else {
                        this.value = "#" + value;
                break;
    toLowerCase(){
        return this.value.toLowerCase();
export function CGFloat(num) {
    return Number(num);
export enum VerticalAlignment{
    top = "top",
    center = "center",
    bottom = "bottom"
export enum HorizontalAlignment{
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
leading = "left", center = "center", trailing = "right" } export enum Alignment{ top = "top", center = "center", bottom = "bottom", leading = "left", trailing = "right", topLeading = "topLeading", topTrailing = "topTrailing", bottomLeading = "bottomLeading", bottomTrailing = "bottomTrailing" } export enum TextAlignment{ leading = "left", center = "center", trailing = "right" } export var Font = { Weight: { regular: "regular", bold: "bold", semibold: "semibold", heavy: "heavy", light: "light", ultraLight: "ultraLight", black: "black" } } export class CVUParser { context: MemriContext; tokens; index = 0; lastToken; lookup; execFunc; constructor(tokens, context?, lookup?, execFunc?) { this.context = context; this.tokens = tokens; this.lookup = lookup; this.execFunc = execFunc; } peekCurrentToken() { return this.index >= this.tokens.length ? new CVUToken.EOF()//TODO:? : this.tokens[this.index] } popCurrentToken() { if (this.index >= this.tokens.length) { this.lastToken = new CVUToken.EOF();//TODO:? return this.lastToken } this.lastToken = this.tokens[this.index]; ++this.index; return this.lastToken! // Check for out of bound? } parse() { this.index = 0; var result = [];
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
while (true) { let token = this.peekCurrentToken(); if (CVUToken.EOF == token.constructor) { return result } token = this.peekCurrentToken(); if (CVUToken.Newline == token.constructor) { this.popCurrentToken(); continue } var dsl = this.parseViewDSL(); if (dsl.get("sessions") != undefined) { dsl = new CVUParsedSessionsDefinition(dsl.selector ?? "", dsl.name, dsl.domain, dsl.parsed) } else if (dsl.get("views") != undefined) { dsl = new CVUParsedSessionDefinition(dsl.selector ?? "", dsl.name, dsl.domain, dsl.parsed) } result.push(dsl); } } parseViewDSL() { let node = this.parsePrimary(); let token = this.peekCurrentToken(); if (CVUToken.Colon == token.constructor) { this.popCurrentToken(); } return this.parseDefinition(node); } parsePrimary(skipOperator = false) { switch (this.peekCurrentToken().constructor) { case CVUToken.Identifier: return this.parseIdentifierSelector(); case CVUToken.NamedIdentifier: return this.parseNamedIdentifierSelector(); case CVUToken.BracketOpen: return this.parseBracketsSelector(); case CVUToken.String: return this.parseStringSelector(); default: throw new CVUParseErrors.ExpectedDefinition(this.popCurrentToken()) } } parseIdentifierSelector() { // Example: Person { let token = this.popCurrentToken(); if (token.constructor != CVUToken.Identifier) { throw new CVUParseErrors.ExpectedIdentifier(this.lastToken!); } let type = token.value; // Example: Person[name = 'john'] token = this.peekCurrentToken(); if (token.constructor == CVUToken.BracketOpen) { this.popCurrentToken(); token = this.peekCurrentToken(); if (token.constructor == CVUToken.BracketClose) { this.popCurrentToken(); type += "[]" } else { // TODO } }