// compile a prog block inside an existing scope internal void CompileProg(NodeListParser nlp) { Logger.WriteLine(2, "CompileProg <{0}>", nlp); // iterate over the action items in the prog block while (!nlp.Done) { // value -- special handler if (nlp.IsValue || nlp.IsValueCallable) { if (!CompileHandler("--value", nlp)) { nlp.Syntax("bare value not allowed"); } // callable function, call it } else if (nlp.IsCallable) { if (nlp.IsFunc && nlp.CurrentIdent.Sym.Keyword == Keywords.ELSE) { return; // sneaky! } var sexpr = nlp.GetSexprNode(); nlp.Expect(sexpr.DataType == DataTypes.Void, "void function"); CompileSexpr(sexpr, nlp); // list -- special handler } else if (nlp.IsList) { var handler = Symbols.Find("--list") as BuiltinSymbol; if (handler != null) { CompileBuiltin(handler, nlp.GetParser()); } else { nlp.Unexpected("unknown function"); } } else { nlp.Expected("function call"); } } }
protected OptionValue GetOption(NodeListParser nlp) { if (nlp.IsNumber) { return(OptionValue.Create(nlp.GetNumber().Value)); } if (nlp.IsBool) { return(OptionValue.Create(nlp.GetBool().Value ? 1 : 0)); } // note that options are case insensitive if (nlp.IsIdent && _optionlookup.ContainsKey(nlp.CurrentIdent.Name.ToLower())) { return(_optionlookup[nlp.GetIdent().Name.ToLower()]); } nlp.Expected("number or option keyword"); return(OptionValue.Default); }
PositionOrZone ParsePositionOrZone(NodeListParser nlp) { if (nlp.IsConstant) { var value = nlp.GetValue(); if (value is PositionValue || value is ZoneValue) { return new PositionOrZone { Value = value } } ; else { } } nlp.Expected("position or zone"); return(null); }
// Compile an argument of given type void CompileArg(Type type, NodeListParser nlp) { Logger.WriteLine(4, "CompileArg {0} <{1}>", type, nlp); var func = _typeactiondict.SafeLookup(type); // special for variable assignment and implicit definition if (type == typeof(Variable)) { var ident = nlp.GetIdent(); var datatype = DataTypes.Bool; // TODO: handle other types if (ident.Sym.IsVariable) { nlp.Expect(ident.Sym.DataType == datatype, "variable of type {0}", datatype); } else if (ident.Sym.IsUndef) { Symbols.DefineVariable(ident.Name, datatype, BoolValue.False); } else { nlp.Expected("defined variable"); } _gen.EmitRefVar(ident.Sym); // handle these separately, could be variable or function } else if (type.IsSubclassOf(typeof(TypedValue))) { // TODO: type checking CompileValue(type, nlp); //var exptype = TypedValue.DataTypeDict.SafeLookup(type); //var rettype = CompileValue(type, nlp); //nlp.Expect(rettype == exptype, "value of type {0}", exptype); // direct lookup gets special cases; else continue } else if (func != null) { var value = func(type, nlp, this); _gen.EmitLoadValue(value); // Array means parse a list of this type } else if (type.IsArray) { var nargs = 0; for (var nlp2 = nlp.GetParser(); !nlp2.Done; nargs++) { CompileArg(type.GetElementType(), nlp2); } _gen.EmitToArray(type, nargs); // List<> means parse a tail of this type } else if (type.IsGenericType && type.Name.StartsWith("List")) { var nargs = 0; for (; !nlp.Done; ++nargs) { CompileArg(type.GetGenericArguments()[0], nlp); } _gen.EmitToList(type, nargs); // Pair<> means parse a pair of arbitrary types } else if (type.IsGenericType && type.Name.StartsWith("Pair")) { var nlp2 = nlp.GetParser(); foreach (var subtype in type.GetGenericArguments()) { CompileArg(subtype, nlp2); } _gen.EmitToPair(type); // nested prog block } else if (type.IsSubclassOf(typeof(CodeBase))) { var info = Symbols.PredefScopeDict.First(kv => kv.Value.CodeType == type).Value; CompileProg(info, nlp); } else if (type == typeof(PositionOrDirection)) { CompilePositionOrDirection(nlp); // function call on built in } else if (nlp.IsSexpr) { var sexpr = nlp.GetSexprNode(); var datatype = TypedValue.DataTypeDict.SafeLookup(type); nlp.Expect(sexpr.DataType == datatype, "value of type {0}", datatype); CompileBuiltin(sexpr.Sym as BuiltinSymbol, NodeListParser.Create(sexpr.Args, Symbols)); } else { nlp.Syntax("unknown type {0}", type); } }