[Declarations::] Declarations. Reading declarations from a file. @h Keeping the syntax module happy. We are going to need to use the sentence-breaking apparatus from the //syntax// module, which means that the following four nonterminals need to exist. But in fact they are really just placeholders -- they are wired so that they can never match any text. = ::= ... ==> { fail } ::= ... ==> { fail } ::= ... ==> { fail } ::= ... ==> { fail } @h A sort of REPL. The following function reads a file whose name is in |arg|, feeds it into the lexer, builds a syntax tree of its sentences, and then walks through that tree, applying the Preform nonterminal to each sentence. In effect, this is a read-evaluate-print loop. = parse_node_tree *syntax_tree = NULL; kind *kind_vars[27]; void Declarations::load_from_file(text_stream *arg) { filename *F = Filenames::from_text(arg); feed_t FD = Feeds::begin(); source_file *sf = TextFromFiles::feed_into_lexer(F, NULL_GENERAL_POINTER); wording W = Feeds::end(FD); if (sf == NULL) { PRINT("File has failed to open\n"); return; } syntax_tree = SyntaxTree::new(); Sentences::break(syntax_tree, W); for (int i=1; i<=26; i++) { kind_vars[i] = Kinds::var_construction(i, NULL); } kind_checker_mode = MATCH_KIND_VARIABLES_AS_UNIVERSAL; SyntaxTree::traverse(syntax_tree, Declarations::parse); } @ @d KIND_VARIABLE_FROM_CONTEXT Declarations::kv = kind *Declarations::kv(int v) { return kind_vars[v]; } void Declarations::parse(parse_node *p) { if (Node::get_type(p) == SENTENCE_NT) { wording W = Node::get_text(p); (W); } } @ @e kind_relationship_CLASS @d EXACT_PARSING_BITMAP (KIND_SLOW_MC) = DECLARE_CLASS(kind_relationship) typedef struct kind_relationship { struct kind *sub; struct kind *super; CLASS_DEFINITION } kind_relationship; @ = ::= new unit | ==> @ new unit ... | ==> @ new enum | ==> @ new enum ... | ==> @ new kind ... of | ==> @ * = | ==> @ = | ==> @ | ==> @ | ==> @ compatible with | ==> @ ... which varies | ==> { -, - } ... ==> @ ::= ( ) | ==> { pass 1 } + | ==> @ - | ==> @ * | ==> @ over | ==> @ % | ==> @ to the nearest | ==> @ - | ==> @ square root of | ==> @ real square root of | ==> @ cube root of | ==> @ join of and | ==> @ meet of and | ==> @ first term of | ==> @ second term of | ==> @ dereference | ==> @ weaken | ==> @ super of | ==> @ substitute for in | ==> @ void | ==> { -, K_void } | ==> { pass 1 } ==> { pass 1 } ::= <= | ==> @ is definite ==> @ @ = kind *K = RP[1]; PRINT("'% = PRINT("'% = kind *K1 = RP[1]; kind *K2 = RP[2]; switch (Kinds::compatible(K1, K2)) { case NEVER_MATCH: PRINT("'% = kind *K = RP[1]; PRINT("Kind already exists: '%u'\n", K); ==> { fail } @ = kind *K = Kinds::new_base(GET_RW(, 1), K_value); Kinds::Behaviour::convert_to_unit(K); PRINT("'% = kind *K = Kinds::new_base(GET_RW(, 1), K_value); Kinds::Behaviour::convert_to_enumeration(K); PRINT("'% = kind *X = RP[1]; kind *K = Kinds::new_base(GET_RW(, 1), X); kind_relationship *KR = CREATE(kind_relationship); KR->sub = K; KR->super = X; PRINT("'% = kind *K1 = (kind *) RP[1]; kind *K2 = (kind *) RP[2]; kind *K = (kind *) RP[3]; Kinds::Dimensions::make_unit_derivation(K1, K2, K); PRINT("'% = kind *KV = RP[1]; kind *K = RP[2]; kind_vars[KV->kind_variable_number] = K; ==> { -, K } PRINT("'% = PRINT("No such kind as '%W'\n", W); ==> { fail } @ = PRINT("Declaration not understood: '%W'\n", W); ==> { fail } @ = int op = PLUS_OPERATION; @; @ = int op = MINUS_OPERATION; @; @ = int op = TIMES_OPERATION; @; @ = int op = DIVIDE_OPERATION; @; @ = int op = REMAINDER_OPERATION; @; @ = int op = APPROXIMATION_OPERATION; @; @ = kind *K1 = RP[1]; kind *K2 = RP[2]; ==> { - , Kinds::Dimensions::arithmetic_on_kinds(K1, K2, op) } @ = int op = UNARY_MINUS_OPERATION; @; @ = int op = ROOT_OPERATION; @; @ = int op = REALROOT_OPERATION; @; @ = int op = CUBEROOT_OPERATION; @; @ = kind *K = RP[1]; ==> { - , Kinds::Dimensions::arithmetic_on_kinds(K, NULL, op) } @ = kind *K1 = RP[1]; kind *K2 = RP[2]; ==> { - , Latticework::join(K1, K2) } @ = kind *K1 = RP[1]; kind *K2 = RP[2]; ==> { - , Latticework::meet(K1, K2) } @ = kind *K = RP[1]; switch (Kinds::arity_of_constructor(K)) { case 0: ==> { -, NULL }; break; case 1: ==> { -, Kinds::unary_construction_material(K) }; break; case 2: { kind *X, *Y; Kinds::binary_construction_material(K, &X, &Y); ==> { -, X }; break; } } @ = kind *K = RP[1]; switch (Kinds::arity_of_constructor(K)) { case 0: ==> { -, NULL }; break; case 1: ==> { -, NULL }; break; case 2: { kind *X, *Y; Kinds::binary_construction_material(K, &X, &Y); ==> { -, Y }; break; } } @ = kind *K = RP[1]; ==> { - , Kinds::weaken(K, K_object) } @ = kind *K = RP[1]; ==> { - , Kinds::dereference_properties(K) } @ = kind *K = RP[1]; ==> { - , Latticework::super(K) } @ = kind *K1 = RP[1]; kind *K2 = RP[2]; ==> { Kinds::conforms_to(K1, K2), - } @ = kind *K = RP[1]; ==> { Kinds::Behaviour::definite(K), - } @ = kind *K1 = RP[1]; kind *KV = RP[2]; kind *K2 = RP[3]; kind *slate[27]; for (int i=1; i<=26; i++) slate[i] = NULL; slate[KV->kind_variable_number] = K1; int changed; ==> { -, Kinds::substitute(K2, slate, &changed, FALSE) } @ @d HIERARCHY_GET_SUPER_KINDS_CALLBACK Declarations::super @d HIERARCHY_ALLOWS_SOMETIMES_MATCH_KINDS_CALLBACK Declarations::sometimes = int Declarations::le(kind *K1, kind *K2) { while (K1) { if (Kinds::eq(K1, K2)) return TRUE; K1 = Declarations::super(K1); } return FALSE; } kind *Declarations::super(kind *K1) { kind_relationship *KR; LOOP_OVER(KR, kind_relationship) if (Kinds::eq(K1, KR->sub)) return KR->super; return NULL; } int Declarations::sometimes(kind *from) { while (from) { if (Kinds::eq(from, K_object)) return TRUE; from = Latticework::super(from); } return FALSE; }