Files
sune/dist/index.html
2025-09-15 05:47:51 +00:00

317 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html><html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Hi Language</title>
<link rel="preconnect" href="https://cdn.jsdelivr.net">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@5.8.1/github-markdown-light.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/styles/github.min.css">
<style>
*{scroll-behavior:smooth}
.markdown-body{font-size:16px;line-height:1.7}
.markdown-body pre{overflow:auto}
.markdown-body code:not(pre code){background:rgba(175,184,193,.2);padding:.2em .4em;border-radius:6px}
.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{scrollbar-width:none}
.btn{transition:.15s transform}.btn:active{transform:scale(.98)}
.anchor{scroll-margin-top:72px}
pre{position:relative;border:1px solid #e5e7eb;border-radius:.75rem}
.code-actions{position:absolute;top:.5rem;right:.5rem;display:flex;gap:.5rem;align-items:center}
.copy-btn{background:#0f172a;color:#fff;border-radius:.5rem;padding:.2rem .5rem;font-size:.75rem;opacity:.9}
.char-c{font-size:.75rem;color:#64748b}
@media (max-width:480px){.char-c{display:none}}
.anchor-link{margin-left:.5rem;color:#9ca3af;text-decoration:none}.anchor-link:hover{color:#6b7280}
</style>
<meta charset="utf-8">
<title>Sune</title>
<link rel="icon" type="image/avif" href="https://sune.planetrenox.com/✺.avif">
<script src="https://cdn.jsdelivr.net/npm/tiny-ripple@0.2.0"></script>
<style>:root{--safe-bottom:env(safe-area-inset-bottom)}::-webkit-scrollbar{height:8px;width:8px}::-webkit-scrollbar-thumb{background:#e5e7eb;border-radius:999px}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}</style>
<style>html,body{overscroll-behavior-y:contain}</style>
<style></style>
<script>(()=>{let k,v=visualViewport;const f=()=>{removeEventListener('popstate',f),document.activeElement?.blur()};v.onresize=()=>{let o=v.height<innerHeight;o!=k&&((k=o)?(history.pushState({k:1},''),addEventListener('popstate',f)):(removeEventListener('popstate',f),history.state?.k&&history.back()))}})()</script>
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
<body class="bg-white text-gray-900 selection:bg-black/10">
<div class="flex flex-col h-dvh max-h-dvh overflow-hidden">
<header class="sticky top-0 z-20 bg-white/80 backdrop-blur border-b border-gray-200">
<div class="mx-auto w-full max-w-none px-4 py-3 grid grid-cols-3 items-center">
<button id="menuBtn" class="h-9 w-9 rounded-xl bg-gray-100 hover:bg-gray-200 flex items-center justify-center btn" title="Menu"><svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M3 12h18M3 18h18"/></svg></button>
<div class="justify-self-center text-base font-semibold select-none pointer-events-none">Hi Language</div>
<div class="justify-self-end"><a href="https://github.com/hi-language" class="h-9 w-9 rounded-xl bg-gray-100 hover:bg-gray-200 flex items-center justify-center btn" target="_blank" rel="noopener" title="GitHub"><svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 .5A12 12 0 0 0 0 12.64a12.15 12.15 0 0 0 8.2 11.55c.6.11.82-.27.82-.6v-2.17c-3.34.74-4.05-1.65-4.05-1.65a3.29 3.29 0 0 0-1.36-1.82c-1.1-.78.09-.77.09-.77a2.6 2.6 0 0 1 1.89 1.29 2.64 2.64 0 0 0 3.61 1 2.66 2.66 0 0 1 .78-1.65c-2.67-.31-5.47-1.36-5.47-6.06A4.8 4.8 0 0 1 6 7.57a4.45 4.45 0 0 1 .12-3.29s1-.33 3.3 1.26a11.39 11.39 0 0 1 6 0c2.3-1.59 3.3-1.26 3.3-1.26.44 1.03.48 2.2.12 3.29a4.79 4.79 0 0 1 1.27 3.32c0 4.72-2.8 5.75-5.47 6.06a2.97 2.97 0 0 1 .84 2.31v3.43c0 .34.22.73.83.6A12.16 12.16 0 0 0 24 12.64 12 12 0 0 0 12 .5Z"/></svg></a></div>
</div>
</header>
<main class="flex-1 overflow-y-auto no-scrollbar">
<section id="hero" class="px-6 sm:px-8 py-10 border-b">
<div class="max-w-3xl mx-auto">
<h1 class="text-3xl sm:text-4xl font-bold tracking-tight">Hi — a corely symbolic language</h1>
<p class="mt-3 text-gray-600">Inspired by JavaScript. Few keywords, many symbols. Designed so the core reads naturally across languages, for the whole world.</p>
</div>
</section>
<div id="docs-content" class="markdown-body max-w-3xl mx-auto px-6 sm:px-8 py-8"></div>
</main>
</div>
<div id="sidebarOverlay" class="fixed inset-0 z-40 bg-black/20 hidden"></div>
<aside id="sidebar" class="fixed inset-y-0 left-0 z-50 w-72 max-w-[85vw] bg-white border-r border-gray-200 shadow-xl transform -translate-x-full transition-transform duration-200 ease-out flex flex-col">
<div class="p-3 border-b flex items-center gap-2"><span class="h-7 w-7 rounded-full bg-gray-900 text-white inline-flex items-center justify-center"></span><span class="font-medium truncate">Hi Language Docs</span></div>
<nav id="sideNav" class="flex-1 p-2 text-sm no-scrollbar overflow-y-auto divide-y"></nav>
</aside>
<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/highlight.min.js"></script>
<script id="md" type="text/markdown">
Meet Hi a corely symbolic language inspired by JavaScript.
It keeps the core mostly symbols and uses keywords only where theyre truly practical.
- Minimal surface: prefer symbols over words.
- Blocks are both objects and functions.
- Privacy with `#private` members.
- Boolean is truthiness by value (see below).
> Print helper: `_()` writes to the console.
## Hello, world
~~~js
// Hello World in Hi
_("Hi world")
~~~
## Declarations and Assignment
- `:` declares a name.
- `=` assigns or mutates a value.
~~~js
greeting: "Hi"
name: "Orion"
greeting = greeting + ", " + name
_(greeting) // "Hi, Orion"
~~~
## Blocks (object + function in one)
In Hi, `{}` is a Block. It can hold properties and executable code.
A Block is both an object and a function at the same time.
### Function Block
~~~js
sayHi: {
_("Hi")
}
sayHi() // invokes the block
~~~
### Object Block
Public vs private fields; `#` marks private members.
~~~js
player: {
name: "Orion" // public
#hp: 100 // private
}
_(player.name) // "Orion"
// _(player.#hp) // error: private
~~~
### Hybrid Block
Blocks can expose methods and hold private state.
~~~js
counter: {
#value: 0
inc: {
#value = #value + 1
_("The count is now: " + #value)
#value // last expression returns
}
}
counter.inc() // "The count is now: 1"
counter.inc() // "The count is now: 2"
~~~
### Parameters and returns
- Parameters use `(name, ...)` before the Block.
- Like Rust, the last expression is returned (no `return` keyword).
~~~js
withParams: (str) {
_(str)
str // returned
}
add: (a, b) { a + b }
_( add(2, 3) ) // 5
~~~
## Truthiness and Equality
Truthiness is value-based:
~~~js
0 // falsy (the official false)
!0 // truthy (the official true)
4 // truthy
"" // falsy (truthy if non-empty)
{} // falsy (truthy if it has content)
[] // falsy (truthy if it has content)
-0 // falsy / null / undefined (represents “empty”)
~~~
Equality:
~~~js
== // equivalent to JS ===
~~~
## Conditionals (ternary-style Blocks)
A conditional is an expression that selects a Block.
~~~js
// if
(cond) ? { /* then */ }
// if / else
(cond) ? { /* then */ } : { /* else */ }
// expression result is the last Blocks last expression
tern: (cond) ? { "A" } : { "B" }
~~~
Multi-branch:
~~~js
score: 85
grade: (score > 90) ? { "A" }
: (score > 80) ? { "B" }
: { "C" }
_(grade) // "B"
~~~
## Arrays
~~~js
primes: [2, 3, 5, 7]
// Access
firstPrime: primes[0]
// Mutation
primes[0] = 1
_(primes) // [1, 3, 5, 7]
~~~
## Loops
`* { ... }` after a loop header runs the Block each iteration.
~~~js
// for (init; test; step)
(i: 0; i < 5; i = i + 1) * {
_(i)
}
// while
(!0) * {
// do something forever...
^ // break when done
}
// Controls
>> // continue
^ // break
~~~
## Bridging examples
Closures over private state:
~~~js
makeCounter: {
#v: 0
{
inc: { #v = #v + 1; #v }
value: { #v }
}
}
c: makeCounter()
c.inc() // 1
c.inc() // 2
c.value() // 2
~~~
Tiny program with input and branching:
~~~js
welcome: (name) {
msg: (name && name != "") ? { "Hi, " + name + "!" } : { "Hi!" }
_(msg)
msg
}
welcome("Ada") // "Hi, Ada!"
welcome("") // "Hi!"
~~~
## Notes
- Comments use `//`.
- Strings are `"..."`.
- Blocks return their last expression.
- Private members (`#x`) are visible only inside their Block (and nested Blocks that resolve to it).
---
Hi is still in active development. This page will grow with specs, a reference, and a playground. Contributions and feedback are welcome!
</script>
<script>
document.addEventListener('DOMContentLoaded',()=>{
const $=s=>document.querySelector(s),$$=s=>[...document.querySelectorAll(s)];
const md=window.markdownit({html:true,linkify:true,typographer:true,breaks:true});
const slug=s=>s.toLowerCase().trim().replace(/[^\w\- ]+/g,'').replace(/\s+/g,'-');
const root=$('#docs-content');root.innerHTML=md.render($('#md')?.textContent||'');
const heads=$$('#docs-content h2, #docs-content h3');
heads.forEach(h=>{
const titleText=(h.childNodes[0]?.nodeValue||'').trim();
h.id=slug(titleText);h.classList.add('anchor');
const a=document.createElement('a');a.href='#'+h.id;a.className='anchor-link';a.innerHTML='#';h.appendChild(a);
});
$$('#docs-content pre>code').forEach(code=>{
window.hljs&&hljs.highlightElement(code);
const pre=code.parentElement,t=code.textContent||'',box=document.createElement('div'),btn=document.createElement('button'),meta=document.createElement('span');
btn.className='copy-btn';btn.textContent='Copy';
btn.onclick=async()=>{try{await navigator.clipboard.writeText(code.innerText);btn.textContent='Copied';setTimeout(()=>btn.textContent='Copy',1100)}catch{}};
meta.className='char-c';meta.textContent=(t.length>=1e3?`${(t.length/1e3).toFixed(1)}K`:t.length)+' chars';
box.className='code-actions';box.append(meta,btn);pre.appendChild(box);
});
const nav=$('#sideNav');
if(nav){
const frag=document.createDocumentFragment();
heads.forEach(h=>{
const a=document.createElement('a'),title=(h.childNodes[0]?.nodeValue||'').replace(/\s*#\s*$/,'').trim();
a.href='#'+h.id;a.className=(h.tagName==='H3'?'pl-6 ':'')+'block px-2 py-1 rounded-lg hover:bg-gray-100 text-gray-700';a.textContent=title;frag.appendChild(a);
});
nav.appendChild(frag);
const links=[...nav.querySelectorAll('a')];
const io=new IntersectionObserver(es=>{es.forEach(e=>{if(e.isIntersecting){const id='#'+e.target.id;links.forEach(L=>L.classList.toggle('bg-gray-100 font-medium',L.getAttribute('href')===id))}})},{rootMargin:'-72px 0px -50% 0px'});
heads.forEach(h=>io.observe(h));
links.forEach(L=>L.addEventListener('click',()=>toggleSidebar(false)));
}
const overlay=$('#sidebarOverlay'),sidebar=$('#sidebar'),toggleSidebar=v=>{overlay.classList.toggle('hidden',!v);sidebar.classList.toggle('-translate-x-full',!v)};
$('#menuBtn')?.addEventListener('click',()=>toggleSidebar(true));
overlay?.addEventListener('click',()=>toggleSidebar(false));
document.addEventListener('keydown',e=>{if(e.key==='Escape')toggleSidebar(false)});
});
</script>
</body>
</html>