Prexonite, a .NET hosted scripting language with a focus on meta-programming and embedded DSLs
0

Configure Feed

Select the types of activity you want to include in your feed.

Make prx 2 the default prelude

Closes PRX-67

Christian Klauser (Jun 15, 2024, 6:26 PM +0200) 021aa14d 63930e96

+113 -181
+44
Prexonite/Commands/ReExportNamespaceExportsTopLevel.cs
··· 1 + using System.Collections.Immutable; 2 + using Prexonite.Commands.List; 3 + using Prexonite.Compiler; 4 + using Prexonite.Compiler.Symbolic; 5 + 6 + namespace Prexonite.Commands; 7 + 8 + public class ReExportNamespaceExportsTopLevel(Loader loader) : ICommand 9 + { 10 + public PValue Run(StackContext sctx, PValue[] args) 11 + { 12 + if (args.Length < 1) 13 + { 14 + throw new PrexoniteException("Re-exporting namespace export at the top level requires at least one argument."); 15 + } 16 + 17 + var nsPathBuf = Map._ToEnumerable(sctx, args[0]).Select(x => x.CallToString(sctx)).ToImmutableArray(); 18 + if (nsPathBuf.Length == 0) 19 + { 20 + return PType.Null; 21 + } 22 + 23 + var nsPath = nsPathBuf.AsSpan(); 24 + ISymbolView<Symbol> currentScope = loader.Symbols; 25 + 26 + while (nsPath.Length > 0) 27 + { 28 + if (!currentScope.TryGet(nsPath[0], out var resolved) || !resolved.TryGetNamespaceSymbol(out var resolvedNs)) 29 + { 30 + throw new PrexoniteException($"Cannot find '{nsPath[0]}' of namespace '{string.Join(".", nsPathBuf)}'."); 31 + } 32 + 33 + currentScope = resolvedNs.Namespace; 34 + nsPath = nsPath[1..]; 35 + } 36 + 37 + foreach (var (name, symbol) in currentScope) 38 + { 39 + loader.TopLevelSymbols.Declare(name, symbol); 40 + } 41 + 42 + return PType.Null; 43 + } 44 + }
+7 -1
Prexonite/Compiler/Build/Plan.cs
··· 41 41 Source.FromEmbeddedPrexoniteResource("prxlib.sys.pxs"), 42 42 Source.FromEmbeddedPrexoniteResource("prxlib.prx.v1.pxs"), 43 43 Source.FromEmbeddedPrexoniteResource("prxlib.prx.v1.prelude.pxs"), 44 + Source.FromEmbeddedPrexoniteResource("prxlib.prx.v2.prelude.pxs"), 44 45 }; 45 46 46 47 public static IPlan CreateDefault() ··· 58 59 CancellationToken token) 59 60 { 60 61 var plan = new SelfAssemblingPlan(); 61 - if (stdPreference == StandardLibraryPreference.Default) 62 + if (stdPreference is StandardLibraryPreference.Default or StandardLibraryPreference.NoPrelude) 62 63 { 63 64 // Provide modules that the standard library may be composed of. No dependency checking. 64 65 await Task.WhenAll(_stdLibModules.Select(s => plan.RegisterModule(s, token))); 65 66 66 67 // Describe standard library. Dependencies must be satisfied 67 68 plan.StandardLibrary.Add(new("sys", new(0, 0))); 69 + if (stdPreference != StandardLibraryPreference.NoPrelude) 70 + { 71 + plan.StandardLibrary.Add(new("prx.prelude", new(2, 0))); 72 + } 68 73 } 69 74 return plan; 70 75 } ··· 78 83 public enum StandardLibraryPreference 79 84 { 80 85 Default = 0, 86 + NoPrelude = 1, 81 87 None, 82 88 }
+3
Prexonite/Compiler/Loader.cs
··· 1135 1135 BuildCommands.AddCompilerCommand( 1136 1136 BuildGetLoaderCommand, 1137 1137 (sctx, _) => sctx.CreateNativePValue(this)); 1138 + 1139 + BuildCommands.AddCompilerCommand("re_export_namespace_exports_top_level", 1140 + new ReExportNamespaceExportsTopLevel(this)); 1138 1141 } 1139 1142 1140 1143
+1
Prexonite/Prexonite.csproj
··· 66 66 <EmbeddedResource Include="prxlib\prx.prim.pxs" /> 67 67 <EmbeddedResource Include="prxlib\prx.v1.pxs" /> 68 68 <EmbeddedResource Include="prxlib\prx.v1.prelude.pxs" /> 69 + <EmbeddedResource Include="prxlib\prx.v2.prelude.pxs" /> 69 70 <EmbeddedResource Include="prxlib\sys.pxs" /> 70 71 <GrammarFragment Include="Compiler\Grammar\Footer.atg" /> 71 72 <TextTemplate Include="**\*.tt" />
+3 -1
Prexonite/prxlib/prx.core.pxs
··· 70 70 71 71 namespace math export(*),prx.prim(abs,ceiling,exp,floor,log,max,min,pi,round,sin,cos,sqrt,tan); 72 72 73 - namespace ct export(*),prx.prim( 73 + namespace ct { 74 + declare(re_export_namespace_exports_top_level = ref command "re_export_namespace_exports_top_level"); 75 + } export(*),prx.prim( 74 76 create_source_position, get_unscoped_ast_factory, 75 77 macro\pack => pack, macro\unpack => unpack, macro\reference => macro_reference, call\macro, 76 78 entityref_to);
+3 -167
Prexonite/prxlib/prx.v1.prelude.pxs
··· 7 7 // This module should only be used in situations where the former is not an option. 8 8 9 9 Name prx::prelude/1.0; 10 - 11 - declare { 12 - command: 13 - print,println, 14 - meta, 15 - boxed, 16 - string_concat, 17 - concat, 18 - map, 19 - flat_map, 20 - select, 21 - foldl, 22 - foldr, 23 - dispose, 24 - call\perform, 25 - thunk, 26 - asthunk, 27 - force, 28 - toseq, 29 - call\member\perform, 30 - caller, 31 - pair, 32 - unbind, 33 - sort, 34 - orderby, 35 - LoadAssembly, 36 - debug, 37 - setcenter, 38 - setleft, 39 - setright, 40 - all, 41 - where, 42 - skip, 43 - limit, 44 - take, 45 - abs, 46 - ceiling, 47 - exp, 48 - floor, 49 - log, 50 - max, 51 - min, 52 - pi, 53 - round, 54 - sin, 55 - cos, 56 - sqrt, 57 - tan, 58 - char, 59 - count, 60 - distinct, 61 - union, 62 - unique, 63 - frequency, 64 - groupby, 65 - intersect, 66 - call\tail\perform, 67 - list, 68 - each, 69 - exists, 70 - forall, 71 - CompileToCil, 72 - takewhile, 73 - except, 74 - range, 75 - reverse, 76 - headtail, 77 - append, 78 - sum, 79 - contains, 80 - chan, 81 - call\async\perform, 82 - async_seq, 83 - call\sub\perform, 84 - pa\ind, 85 - pa\mem, 86 - pa\ctor, 87 - pa\check, 88 - pa\cast, 89 - pa\smem, 90 - pa\fun\call, 91 - pa\flip\call, 92 - pa\call\star, 93 - then, 94 - id, 95 - const, 96 - (+), 97 - (-), 98 - (*), 99 - (/), 100 - $mod, 101 - (^), 102 - (&), 103 - (|), 104 - $xor, 105 - (==), 106 - (!=), 107 - (>), 108 - (>=), 109 - (<), 110 - (<=), 111 - (-.), 112 - $complement, 113 - $not, 114 - create_enumerator, 115 - create_module_name, 116 - create_source_position, 117 - get_unscoped_ast_factory, 118 - seqconcat, 119 - macro command: 120 - call, 121 - call\member, 122 - call\tail, 123 - call\async, 124 - call\sub, 125 - call\sub\interpret, 126 - macro\pack, 127 - macro\unpack, 128 - macro\reference, 129 - call\star, 130 - call\macro, 131 - call\macro\impl, 132 - entityref_to, 133 - // constructor (new T) 134 - create_Bool, 135 - create_Char, 136 - create_Hash, 137 - create_Int, 138 - create_List, 139 - create_Null, 140 - create_Object, 141 - create_Real, 142 - create_String, 143 - create_Structure, 144 - // type check (is T) 145 - is_Bool, 146 - is_Char, 147 - is_Hash, 148 - is_Int, 149 - is_List, 150 - is_Null, 151 - is_Object, 152 - is_Real, 153 - is_String, 154 - is_Structure, 155 - // type cast (~T) 156 - to_Bool, 157 - to_Char, 158 - to_Hash, 159 - to_Int, 160 - to_List, 161 - to_Null, 162 - to_Object, 163 - to_Real, 164 - to_String, 165 - to_Structure, 166 - // static call (~T.method) 167 - static_call_Bool, 168 - static_call_Char, 169 - static_call_Hash, 170 - static_call_Int, 171 - static_call_List, 172 - static_call_Null, 173 - static_call_Object, 174 - static_call_Real, 175 - static_call_String, 176 - static_call_Structure 10 + References { 11 + prx/1.0 177 12 }; 13 + build does re_export_namespace_exports_top_level(["prx", "v1"]);
+9
Prexonite/prxlib/prx.v2.prelude.pxs
··· 1 + //PRX 2 + 3 + Name prx::prelude/2.0; 4 + References { 5 + sys/0.0 6 + }; 7 + 8 + namespace import sys.*; 9 + build does sys.ct.re_export_namespace_exports_top_level(["sys"]);
+17 -12
PrexoniteTests/Tests/Configurations/ModuleCache.cs
··· 55 55 56 56 ITargetDescription _loadLegacySymbols() 57 57 { 58 - var moduleName = new ModuleName("prx.v1", new(0, 0)); 59 - var desc = Cache.CreateDescription(moduleName, 60 - Source.FromEmbeddedPrexoniteResource("prxlib.prx.v1.prelude.pxs"), 61 - "prxlib/prx.v1.prelude.pxs", 62 - Enumerable.Empty<ModuleName>()); 63 - Cache.TargetDescriptions.Add(desc); 64 - Cache.Build(moduleName); 58 + var preludeName = new ModuleName("prx.prelude", new(1, 0)); 59 + Cache.Build(preludeName); 65 60 // Important: lookup the target description in order to get the cached description 66 - return Cache.TargetDescriptions[moduleName]; 61 + return Cache.TargetDescriptions[preludeName]; 67 62 68 63 } 69 64 ··· 82 77 { 83 78 var v1Name = new ModuleName("prx", new(1, 0)); 84 79 var v1Desc = Cache.CreateDescription(v1Name, Source.FromEmbeddedPrexoniteResource("prxlib.prx.v1.pxs"), 85 - "prxlib/prx.v1.pxs", Enumerable.Empty<ModuleName>()); 80 + "prxlib/prx.v1.pxs", []); 86 81 Cache.TargetDescriptions.Add(v1Desc); 87 82 88 83 var primName = new ModuleName("prx.prim", new(0, 0)); 89 84 var primDesc = Cache.CreateDescription(primName, Source.FromEmbeddedPrexoniteResource("prxlib.prx.prim.pxs"), 90 - "prxlib/prx.prim.pxs", Enumerable.Empty<ModuleName>()); 85 + "prxlib/prx.prim.pxs", []); 91 86 Cache.TargetDescriptions.Add(primDesc); 92 87 93 88 var coreName = new ModuleName("prx.core", new(0, 0)); ··· 95 90 "prxlib/prx.core.pxs", primName.Singleton()); 96 91 Cache.TargetDescriptions.Add(coreDesc); 97 92 93 + var preludeV1Name = new ModuleName("prx.prelude", new(1, 0)); 94 + var preludeV1Desc = Cache.CreateDescription(preludeV1Name, Source.FromEmbeddedPrexoniteResource("prxlib.prx.v1.prelude.pxs"), 95 + "prxlib/prx.v1.prelude.pxs", v1Name.Singleton()); 96 + Cache.TargetDescriptions.Add(preludeV1Desc); 97 + 98 98 var sysName = new ModuleName("sys", new(0, 0)); 99 99 var desc = Cache.CreateDescription(sysName, Source.FromEmbeddedPrexoniteResource("prxlib.sys.pxs"), "prxlib/sys.pxs", 100 - new[]{ primName, coreName }); 100 + [primName, coreName]); 101 101 Cache.TargetDescriptions.Add(desc); 102 + 103 + var preludeV2Name = new ModuleName("prx.prelude", new(2, 0)); 104 + var preludeV2Desc = Cache.CreateDescription(preludeV2Name, Source.FromEmbeddedPrexoniteResource("prxlib.prx.v2.prelude.pxs"), 105 + "prxlib/prx.v2.prelude.pxs", sysName.Singleton()); 106 + Cache.TargetDescriptions.Add(preludeV2Desc); 102 107 103 108 Cache.Build(sysName); 104 109 return Cache.TargetDescriptions[sysName]; ··· 133 138 new ModuleName(Path.GetFileNameWithoutExtension(dep), new(0, 0))).ToArray(); 134 139 135 140 // Manually add legacy symbol and stdlib dependencies 136 - var effectiveDependencies = dependencyNames.Append(LegacySymbolsDescription.Name).Append(stdlibDescription.Name); 141 + var effectiveDependencies = dependencyNames.Append(stdlibDescription.Name).Append(LegacySymbolsDescription.Name); 137 142 var desc = Cache.CreateDescription(moduleName, file.ToSource(), path, effectiveDependencies); 138 143 _trace.TraceEvent(TraceEventType.Information, 0, 139 144 "Adding new target description for cache on thread {0}: {1}.", Thread.CurrentThread.ManagedThreadId,
+6
PrexoniteTests/Tests/EmbeddedPrxLibTests.cs
··· 21 21 { 22 22 _checkEmbeddedResource("prxlib.prx.v1.prelude.pxs"); 23 23 } 24 + 25 + [Test] 26 + public void V2Prelude() 27 + { 28 + _checkEmbeddedResource("prxlib.prx.v2.prelude.pxs"); 29 + } 24 30 25 31 [Test] 26 32 public void PrxCore()
+20
PrexoniteTests/Tests/SelfAssemblingPlanTests.cs
··· 30 30 using System.Linq; 31 31 using System.Text; 32 32 using System.Threading; 33 + using System.Threading.Tasks; 33 34 using NUnit.Framework; 35 + using Prexonite; 34 36 using Prexonite.Compiler.Build; 35 37 using Prexonite.Compiler.Build.Internal; 36 38 using Prexonite.Modular; ··· 562 564 Assert.That(lostTarget.Dependencies, Contains.Item(baseModuleName), string.Format("{1} is expected to depend on {0}.", baseModuleName, lostTarget)); 563 565 Assert.That(lostTarget.BuildMessages, Is.Empty, $"{lostTarget} should not have build (error) messages"); 564 566 } 567 + } 568 + 569 + [Test] 570 + public async Task StandardPreludeV2() 571 + { 572 + using var _ = MockFile("file.pxs", 573 + """ 574 + function main() { 575 + println("Hello World"); 576 + return 5 + 4; 577 + } 578 + """ 579 + ); 580 + 581 + var targetDesc = await Sam.AssembleAsync(Source.FromFile(Path.Combine(_basePath, "file.pxs"), Encoding.UTF8)); 582 + var app = await Sam.LoadAsync(targetDesc.Name); 583 + var result = app.Run(new()); 584 + Assert.That(result, Is.EqualTo((PValue)9)); 565 585 } 566 586 }